简体   繁体   English

从 Python 迭代器获取最后一项的最简洁方法

[英]Cleanest way to get last item from Python iterator

What's the best way of getting the last item from an iterator in Python 2.6?从 Python 2.6 中的迭代器获取最后一项的最佳方法是什么? For example, say例如,说

my_iter = iter(range(5))

What is the shortest-code / cleanest way of getting 4 from my_iter ?my_iter获得4的最短代码/最干净的方法是什么?

I could do this, but it doesn't seem very efficient:我可以这样做,但它似乎不是很有效:

[x for x in my_iter][-1]

If you are using Python 3.x:如果您使用的是 Python 3.x:

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

if you are using python 2.7:如果您使用的是 python 2.7:

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


Side Note:边注:

Usually, the solution presented above is what you need for regular cases, but if you are dealing with a big amount of data, it's more efficient to use a deque of size 1. ( source )通常,上面介绍的解决方案是您在常规情况下所需要的,但如果您正在处理大量数据,使用大小为 1 的deque更有效。(来源

from collections import deque

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

dd = deque(aa, maxlen=1)
last_element = dd.pop()
item = defaultvalue
for item in my_iter:
    pass

Use a deque of size 1.使用大小为 1 的deque

from collections import deque

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

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

Short version:精简版:

last_element, = deque(aa, 1)

Probably worth using __reversed__ if it is available如果__reversed__可用,可能值得使用

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

很简单:

max(enumerate(the_iter))[1]

This is unlikely to be faster than the empty for loop due to the lambda, but maybe it will give someone else an idea由于 lambda,这不太可能比空的 for 循环更快,但也许它会给其他人一个想法

reduce(lambda x,y:y,my_iter)

If the iter is empty, a TypeError is raised如果 iter 为空,则引发 TypeError

There's this有这个

list( the_iter )[-1]

If the length of the iteration is truly epic -- so long that materializing the list will exhaust memory -- then you really need to rethink the design.如果迭代的长度真的很长——长到实现列表会耗尽内存——那么你真的需要重新考虑设计。

I would use reversed , except that it only takes sequences instead of iterators, which seems rather arbitrary.我会使用reversed ,除了它只需要序列而不是迭代器,这似乎相当随意。

Any way you do it, you'll have to run through the entire iterator.无论如何,您都必须遍历整个迭代器。 At maximum efficiency, if you don't need the iterator ever again, you could just trash all the values:在最大效率下,如果您不再需要迭代器,您可以丢弃所有值:

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

I think this is a sub-optimal solution, though.不过,我认为这是一个次优的解决方案。

The toolz library provides a nice solution: toolz库提供了一个很好的解决方案:

from toolz.itertoolz import last
last(values)

But adding a non-core dependency might not be worth it for using it only in this case.但是仅在这种情况下使用它可能不值得添加非核心依赖项。

See this code for something similar:有关类似内容,请参阅此代码:

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

you might use it to pick up the last item with:你可以用它来拿起最后一个项目:

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

The question is about getting the last element of an iterator, but if your iterator is created by applying conditions to a sequence, then reversed can be used to find the "first" of a reversed sequence, only looking at the needed elements, by applying reverse to the sequence itself.问题是关于获取迭代器的最后一个元素,但是如果您的迭代器是通过将条件应用于序列来创建的,那么 reversed 可用于查找反向序列的“第一个”,只需查看所需的元素,通过应用与序列本身相反。

A contrived example,一个人为的例子,

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

我只会使用next(reversed(myiter))

Alternatively for infinite iterators you can use:或者,对于无限迭代器,您可以使用:

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

I thought it would be slower then deque but it's as fast and it's actually faster then for loop method ( somehow )我认为它会比deque慢,但它同样快,实际上比 for 循环方法更快(不知何故)

The question is wrong and can only lead to an answer that is complicated and inefficient.这个问题是错误的,只能导致一个复杂而低效的答案。 To get an iterator, you of course start out from something that is iterable, which will in most cases offer a more direct way of accessing the last element.要获得迭代器,您当然要从可迭代的东西开始,这在大多数情况下会提供一种更直接的方式来访问最后一个元素。

Once you create an iterator from an iterable you are stuck in going through the elements, because that is the only thing an iterable provides.一旦你从一个可迭代对象创建了一个迭代器,你就会被困在遍历元素的过程中,因为这是可迭代对象提供的唯一东西。

So, the most efficient and clear way is not to create the iterator in the first place but to use the native access methods of the iterable.因此,最有效和最清晰的方法不是一开始就创建迭代器,而是使用可迭代对象的本机访问方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM