Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/343.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从Python迭代器获取最后一项的最干净方法_Python_Python 3.x_Python 2.7_Iterator - Fatal编程技术网

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

从Python迭代器获取最后一项的最干净方法,python,python-3.x,python-2.7,iterator,Python,Python 3.x,Python 2.7,Iterator,在Python2.6中,从迭代器获取最后一项的最佳方法是什么?比如说 my_iter = iter(range(5)) 从my_iter获取4的最短代码/最干净的方法是什么 我可以这样做,但似乎效率不高: [x for x in my_iter][-1] 我会使用反向,但它只接受序列而不是迭代器,这似乎是任意的 无论如何,都必须运行整个迭代器。以最大效率,如果您不再需要迭代器,您可以丢弃所有值: for last in my_iter: pass # last is now the

在Python2.6中,从迭代器获取最后一项的最佳方法是什么?比如说

my_iter = iter(range(5))
my_iter
获取
4
的最短代码/最干净的方法是什么

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

[x for x in my_iter][-1]

我会使用
反向
,但它只接受序列而不是迭代器,这似乎是任意的

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

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为空,则会引发类型错误

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

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

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

一旦从iterable创建了迭代器,您就会陷入遍历元素的困境,因为这是iterable提供的唯一功能

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

使用大小为1的

from collections import deque

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

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

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

您可以使用它拾取最后一个项目:

[(last, e) for (last, e) in islast(the_iter) if last]
简单到:

max(枚举(iter))[1]

如果您使用的是Python3.x,我将只使用
下一步(反向(myiter))

*_, 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 toolz.itertoolz import last
last(values)

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

问题在于获取迭代器的最后一个元素,但如果迭代器是通过对序列应用条件创建的,则可以使用reversed来查找反转序列的“第一个”,只查看所需的元素,通过对序列本身应用反向

一个人为的例子

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

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

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

我以为它会比
deque
慢,但它和for-loop方法一样快,而且实际上比for-loop方法快(不知何故)

迭代器假设您希望遍历元素,而不是真正访问最后的元素。是什么阻止了你简单地使用范围(5)[-1]?@Frank-我假设实际的迭代器比iter(范围(5))更复杂和/或更远和/或更难控制。@Frank:事实上,它是一个提供迭代器的更复杂的生成器函数。我只是编了一个简单明了的例子,如果你想要迭代器的最后一项,很有可能你做错了什么。但是答案是,实际上没有任何更干净的方法可以通过迭代器进行迭代。这是因为迭代器没有大小,实际上可能永远不会结束,因此可能没有最后一项。(当然,这意味着您的代码将永远运行)。所以一个挥之不去的问题是:你为什么想要迭代器的最后一项?@Peter:请更新你的问题。不要在自己的问题上添加一堆评论。请更新问题并删除注释。reversed()不接受迭代器,只接受序列。它完全不是任意的。反转迭代器的唯一方法是迭代到底,同时将所有项保留在内存中。一、 你需要先把它做一个序列,然后才能反转它。这当然首先违背了迭代器的目的,也意味着你会突然无缘无故地耗尽大量内存。事实上,这是武断的反面@伦纳特——当我说武断时,我的意思是讨厌。我把我的语言技能集中在早上这个时候几个小时后要交的论文上。这很公平。虽然依我看,如果它接受迭代器,会更烦人,因为几乎任何使用它的方法都是个坏主意(tm)为什么要使用占位符“defaultvalue”?为什么不
None
?这正是
None
的用途。您是否认为某些特定于函数的默认值可能是正确的?如果迭代器实际上没有进行迭代,那么带外值比某些误导性的特定于函数的默认值更有意义。如果要使用
None
作为默认值,这是您的选择。无违约并不总是最明智的违约,甚至可能不会超出范围。就我个人而言,我倾向于使用'defaultvalue=object()'来确保它是一个真正唯一的值。我只是指出默认值的选择超出了本例的范围。@S.Lott:也许区分空迭代器和无迭代器的区别是有用的,因为它是最终值所有内置容器类型的迭代器中都存在设计错误?我第一次听说它:)虽然这可能是更快的解决方案,但它依赖于循环中的变量泄漏(对于某些人来说是一个特性,对于其他人来说是一个bug——可能FP的家伙们都感到震惊)。无论如何,Guido说这将始终以这种方式工作,因此使用它是安全的。这实际上是耗尽长序列的最快方式,尽管只比for循环快一点点
>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8
from itertools import islice 
last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples