Ответ 1
item = defaultvalue
for item in my_iter:
pass
Какой лучший способ получить последний элемент из итератора в Python 2.6? Например, скажем
my_iter = iter(range(5))
Каков самый короткий код/самый чистый способ получить 4
из my_iter
?
Я мог бы сделать это, но это не кажется очень эффективным:
[x for x in my_iter][-1]
item = defaultvalue
for item in my_iter:
pass
Используйте deque
размера 1.
from collections import deque
#aa is an interator
aa = iter('apple')
dd = deque(aa, maxlen=1)
last_element = dd.pop()
Если вы используете 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
NB:
Обычно решение, представленное выше, - это то, что вам нужно для обычных случаев, но если вы имеете дело с большим объемом данных, более эффективно использовать deque
размером 1. (источник)
from collections import deque
#aa is an interator
aa = iter('apple')
dd = deque(aa, maxlen=1)
last_element = dd.pop()
Возможно, стоит использовать __reversed__
, если он доступен
if hasattr(my_iter,'__reversed__'):
last = next(reversed(my_iter))
else:
for last in my_iter:
pass
Проще, чем:
max(enumerate(the_iter))[1]
Это вряд ли будет быстрее, чем пустой цикл из-за лямбда, но, возможно, это даст кому-то еще идею
reduce(lambda x,y:y,my_iter)
Если iter пуст, TypeError поднят
Вот этот
list( the_iter )[-1]
Если длина итерации поистине эпична - так долго, что материализация списка исчерпает память - тогда вам действительно нужно переосмыслить дизайн.
Я использовал бы reversed
, за исключением того, что он принимает только последовательности вместо итераторов, что кажется довольно произвольным.
В любом случае, вам придется пройти через весь итератор. При максимальной эффективности, если вам больше не нужен итератор, вы можете просто уничтожить все значения:
for last in my_iter:
pass
# last is now the last item
Я думаю, что это неоптимальное решение.
Смотрите этот код для чего-то подобного:
http://excamera.com/sphinx/article-islast.html
вы можете использовать его для получения последнего элемента с помощью:
[(last, e) for (last, e) in islast(the_iter) if last]
Я бы просто использовал next(reversed(myiter))
Toolz библиотека обеспечивает хорошее решение:
from toolz.itertoolz import last
last(values)
Но добавление неосновной зависимости может не стоить того, чтобы использовать ее только в этом случае.
Вопрос в том, чтобы получить последний элемент итератора, но если ваш итератор создан путем применения условий к последовательности, то обратный можно использовать для поиска "первого" обратной последовательности, только просматривая нужные элементы, применяя Обратно к самой последовательности.
Придуманный пример,
>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8
Вопрос неверен и может привести только к сложному и неэффективному ответу. Чтобы получить итератор, вы, конечно, начинаете с чего-то итеративного, что в большинстве случаев будет предлагать более прямой способ доступа к последнему элементу.
Как только вы создаете итератор из итерабельного, вы застреваете в элементах, потому что это единственное, что обеспечивает итерация.
Таким образом, наиболее эффективным и понятным способом является не создание итератора в первую очередь, а использование собственных методов доступа к итерабельному.