Самый чистый способ получить последний элемент из итератора Python - PullRequest
95 голосов
/ 26 января 2010

Какой лучший способ получить последний элемент из итератора в Python 2.6? Например, скажите

my_iter = iter(range(5))

Какой самый короткий / самый чистый способ получения 4 из my_iter?

Я мог бы сделать это, но это не очень эффективно:

[x for x in my_iter][-1]

Ответы [ 14 ]

84 голосов
/ 26 января 2010
item = defaultvalue
for item in my_iter:
    pass
55 голосов
/ 03 июля 2010

Используйте deque размера 1.

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()
48 голосов
/ 12 января 2018

Если вы используете Python 3.x:

*_, last = iterator # for a better understanding check PEP 448
print(last)

если вы используете Python 2.7:

last = next(iterator)
for last in iterator:
    continue
print last


Примечание:

Обычно представленное выше решение - это то, что вам нужно для обычных случаев, но если вы работаете с большим объемом данных, более эффективно использовать deque размера 1. ( source )

from collections import deque

#aa is an interator
aa = iter('apple')

dd = deque(aa, maxlen=1)
last_element = dd.pop()
32 голосов
/ 06 февраля 2010

Вероятно, стоит использовать __reversed__, если доступно

if hasattr(my_iter,'__reversed__'):
    last = next(reversed(my_iter))
else:
    for last in my_iter:
        pass
22 голосов
/ 06 июня 2011

Так же просто, как:

max(enumerate(the_iter))[1]
19 голосов
/ 26 января 2010

Это вряд ли будет быстрее, чем пустой цикл for из-за лямбды, но, возможно, это даст кому-то еще представление

reduce(lambda x,y:y,my_iter)

Если iter пуст, возникает ошибка TypeError

8 голосов
/ 26 января 2010

Вот это

list( the_iter )[-1]

Если длина итерации действительно эпическая - настолько длинная, что материализация списка исчерпает память - тогда вам действительно нужно переосмыслить дизайн.

4 голосов
/ 26 января 2010

Я бы использовал reversed, за исключением того, что он принимает только последовательности вместо итераторов, что выглядит довольно произвольно

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

for last in my_iter:
    pass
# last is now the last item

Я думаю, что это неоптимальное решение.

1 голос
/ 27 ноября 2018

Библиотека toolz предоставляет хорошее решение:

from toolz.itertoolz import last
last(values)

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

1 голос
/ 12 января 2011

См. Этот код для чего-то похожего:

http://excamera.com/sphinx/article-islast.html

Вы можете использовать его, чтобы забрать последний предмет с:

[(last, e) for (last, e) in islast(the_iter) if last]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...