144

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

my_iter = iter(range(5))

什么是最短代码/最干净的获取4方式my_iter

我可以这样做,但它似乎不是很有效:

[x for x in my_iter][-1]
4

14 回答 14

123
item = defaultvalue
for item in my_iter:
    pass
于 2010-01-26T10:56:42.703 回答
118

如果您使用的是 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 的 a 会更有效。(来源

from collections import deque

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

dd = deque(aa, maxlen=1)
last_element = dd.pop()
于 2018-01-12T19:07:18.160 回答
78

使用deque大小为 1 的 a。

from collections import deque

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

dd = deque(aa, maxlen=1)
last_element = dd.pop()
于 2010-07-02T23:39:12.083 回答
35

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

if hasattr(my_iter,'__reversed__'):
    last = next(reversed(my_iter))
else:
    for last in my_iter:
        pass
于 2010-02-05T23:01:46.400 回答
33

很简单:

max(enumerate(the_iter))[1]
于 2011-06-06T11:24:17.293 回答
23

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

reduce(lambda x,y:y,my_iter)

如果 iter 为空,则引发 TypeError

于 2010-01-26T11:59:14.187 回答
10

有这个

list( the_iter )[-1]

如果迭代的长度真的很长——长到实现列表会耗尽内存——那么你真的需要重新考虑设计。

于 2010-01-26T11:42:54.833 回答
7

我会使用reversed, 除了它只需要序列而不是迭代器,这似乎相当随意。

无论如何,您都必须遍历整个迭代器。在最大效率下,如果您不再需要迭代器,您可以丢弃所有值:

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

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

于 2010-01-26T10:57:54.157 回答
4

toolz库提供一个很好的解决方案:

from toolz.itertoolz import last
last(values)

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

于 2018-11-27T20:00:09.550 回答
1

有关类似内容,请参阅此代码:

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

你可以用它来拿起最后一个项目:

[(last, e) for (last, e) in islast(the_iter) if last]
于 2011-01-12T18:08:48.983 回答
0

问题是关于获取迭代器的最后一个元素,但是如果您的迭代器是通过将条件应用于序列来创建的,那么 reversed 可用于查找反向序列的“第一个”,仅查看所需的元素,通过应用与序列本身相反。

一个人为的例子,

>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8
于 2019-05-17T18:19:17.890 回答
0

我会用next(reversed(myiter))

于 2017-10-24T18:48:49.337 回答
0

或者,对于无限迭代器,您可以使用:

from itertools import islice 
last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples 

我认为它会更慢,deque但它同样快,它实际上比 for 循环方法更快(不知何故)

于 2019-05-31T22:17:07.033 回答
-7

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

一旦你从一个可迭代对象创建了一个迭代器,你就会被困在遍历元素的过程中,因为这是可迭代对象提供的唯一东西。

因此,最有效和最清晰的方法不是一开始就创建迭代器,而是使用可迭代对象的本机访问方法。

于 2010-06-29T02:37:01.527 回答