2015-04-29 9 views
3

Предположим, у меня есть список различных типов:Получить последний элемент типа строки в списке

т.е.

[7, 'string 1', 'string 2', [a, b c], 'string 3', 0, (1, 2, 3)] 

Есть ли Pythonic способ вернуть «строка 3»?

+0

Итак, на основе какого состояния вы хотите этого? – Kasramvd

+0

@ Kasra, условие находится в названии. msgstr "последний элемент строки типа". – Kevin

+0

Подсказка: используйте 'next()' с 'reverseed()' и выражением генератора. –

ответ

12

Если у Вас есть данный тип, вы можете использовать несколько видов постижений, чтобы получить то, что вам нужно.

[el for el in lst if isinstance(el, given_type)][-1] 
# Gives the last element if there is one, else IndexError 

или

next((el for el in reversed(lst) if isinstance(el, given_type)), None) 
# Gives the last element if there is one, else None 

Если это то, что вы делаете достаточно часто, вы можете фактор в функцию:

def get_last_of_type(type_, iterable): 
    for el in reversed(iterable): 
     if isinstance(el, type_): 
      return el 
    return None 
+1

плюс 1 хорошая идея с генератором «обратного». – kojiro

+0

Версия 'next()' позволяет избежать копирования списка, что может повлиять на производительность при определенных обстоятельствах. Однако во многих случаях это микро-оптимизация. Всегда сначала профиль. – Kevin

+0

@ Кевин право. Что еще более важно, он избегает бросать 'IndexError', который должен быть действительно 'None'. Если я прошу последнюю строку в списке, и в списке нет строк, я ожидаю, что мой ответ будет «Нет», чтобы не прерывать поток моей программы! :) –

3

Я бы подумал, что самым простым способом было бы захватить последний элемент отфильтрованного списка.

filter(lambda t: type(t) is type(''), your_list)[-1] 

или

[el for el in your_list if type(el) is type('')][-1] 
+1

Обычно сравнивать типы с 'is', а не с' == ', так как метакласс может переопределить последний. – Kevin

+0

@Kevin спасибо, сделано. – kojiro

+0

Кроме того, 'type ('')' является просто 'str' как в 2.x, так и 3.x. – Kevin

2

обязательное itertools решение:

>>> l = [7, 'string 1', 'string 2', 8, 'string 3', 0, (1, 2, 3)] 
>>> from itertools import dropwhile 
>>> next(dropwhile(lambda x: not isinstance(x, str), reversed(l)), None) 
'string 3' 

Если вы можете «Т использовать импорт по каким-либо причинам, polyfill для itertools.dropwhile выглядит следующим образом:

def dropwhile(predicate, iterable): 
    # dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 
    iterable = iter(iterable) 
    for x in iterable: 
     if not predicate(x): 
      yield x 
      break 
    for x in iterable: 
     yield x 
0

попробовать этот

lst = [7, 'string 1', 'string 2', [a, b c], 'string 3', 0, (1, 2, 3)] 
filtered_string = [ x for x in lst if type(x) is str] 

теперь вы можете получить любой индекс его для последнего индекса

filtered_string[-1] 
Смежные вопросы