从 Python 迭代器获取最后一项的最干净的方法

从 Python 2.6中的迭代器中获取最后一项的最佳方法是什么

my_iter = iter(range(5))

my_iter获得 4的最短代码/最干净的方法是什么?

我可以这样做,但似乎效率不高:

[x for x in my_iter][-1]
81445 次浏览
item = defaultvalue
for item in my_iter:
pass

我会使用 reversed,除了它只接受序列而不是迭代器,这看起来相当随意。

不管用什么方法,都必须遍历整个迭代器。以最高的效率,如果你不再需要迭代器,你可以直接丢弃所有的值:

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

我认为这是一个次优的解决方案,虽然。

还有这个

list( the_iter )[-1]

如果迭代的长度真的很长——如此之长以至于物化列表将耗尽内存——那么您真的需要重新考虑设计。

由于 lambda 的原因,这不太可能比空 for 循环快,但是它可能会给其他人一个想法

reduce(lambda x,y:y,my_iter)

如果 iter 为空,则引发 TypeError

如果可用的话,可能值得使用 __reversed__

if hasattr(my_iter,'__reversed__'):
last = next(reversed(my_iter))
else:
for last in my_iter:
pass

这个问题是错误的,只会导致一个复杂而低效的答案。 要获得迭代器,当然需要从可迭代的元素开始,这在大多数情况下提供了访问最后一个元素的更直接的方法。

一旦您从一个迭代器创建了一个迭代器,您就陷入了遍历元素的困境,因为这是迭代器唯一提供的东西。

因此,最有效和明确的方法不是首先创建迭代器,而是使用迭代器的本机访问方法。

使用大小为1的 deque

from collections import deque


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


dd = deque(aa, maxlen=1)
last_element = dd.pop()

简而言之:

last_element, = deque(aa, 1)

下面的代码与此类似:

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

你可以用它来取最后一样东西:

[(last, e) for (last, e) in islast(the_iter) if last]

简单如下:

max(enumerate(the_iter))[1]

我会用 next(reversed(myiter))

如果你正在使用 Python3.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


附注:

通常,上面提供的解决方案是普通情况下所需要的,但是如果处理的数据量很大,使用大小为1的 deque会更有效率。(来源)

from collections import deque


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


dd = deque(aa, maxlen=1)
last_element = dd.pop()

傻瓜库提供了一个很好的解决方案:

from toolz.itertoolz import last
last(values)

但是添加一个非核心依赖项可能不值得仅在这种情况下使用它。

问题是如何获得迭代器的最后一个元素,但是如果你的迭代器是通过对序列应用条件创建的,那么通过对序列本身应用反向,反向可以用来寻找反向序列的“第一个”,只查看所需的元素。

一个人为的例子,

>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8

你可以使用伟大的 more_itertools库和 last(iterable[, default])函数:

more_itertools.last(iterable[, default])[ 来源]

返回 可迭代的的最后一项,如果 可迭代的为空则返回 违约

>>> last([0, 1, 2, 3])
3
>>> last([], 'some default')
'some default'

如果没有提供 违约,并且在 可迭代的中没有项目,提高 ValueError

它结合了由这里的一些答案提出的 deque方法和一些额外的改进(详见 来源)。