web-dev-qa-db-ja.com

Python iteratorから最後のアイテムを取得する最もクリーンな方法

Python 2.6のイテレータから最後のアイテムを取得する最良の方法は何ですか?たとえば、

my_iter = iter(range(5))

4からmy_iterを取得する最短コード/最もクリーンな方法は何ですか?

私はこれを行うことができましたが、それは非常に効率的ではないようです:

[x for x in my_iter][-1]
97
Peter
item = defaultvalue
for item in my_iter:
    pass
89
Thomas Wouters

サイズ1の deque を使用します。

from collections import deque

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

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

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:

通常、上記のソリューションは通常の場合に必要なものですが、大量のデータを扱う場合は、サイズ1のdequeを使用する方が効率的です( source

from collections import deque

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

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

おそらく__reversed__利用可能な場合

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

単純な:

max(enumerate(the_iter))[1]
25
Chema Cortes

これは、ラムダのために空のforループよりも高速ではありませんが、おそらく他の誰かにアイデアを与えるでしょう

reduce(lambda x,y:y,my_iter)

Iterが空の場合、TypeErrorが発生します

19
John La Rooy

これがあります

list( the_iter )[-1]

反復の長さが本当に壮大な場合、つまりリストの実体化がメモリを使い果たすほど長い場合、設計を再考する必要があります。

9
S.Lott

reversedを使用しますが、イテレータではなくシーケンスのみを使用することを除いて、これはかなりarbitrary意的です。

いずれにしても、イテレーター全体を実行する必要があります。最大限の効率で、イテレーターを再び必要としない場合、すべての値を破棄することができます。

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

しかし、これは次善の解決策だと思います。

4
Chris Lutz

toolz ライブラリは素晴らしいソリューションを提供します:

from toolz.itertoolz import last
last(values)

ただし、コア以外の依存関係を追加しても、この場合にのみ使用する価値はありません。

2
lumbric

同様のコードについては、このコードをご覧ください:

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

あなたはそれを使って最後のアイテムを拾うことができます:

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

私はnext(reversed(myiter))を使用します

0
thomas.mac

無限イテレータの代わりに、次を使用できます:

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

私はそれがdequeより遅いだろうと思ったが、それは同じくらい速く、実際にはforループ方法よりも速い(どういうわけか)

0
qocu

問題は、イテレータの最後の要素を取得することですが、シーケンスに条件を適用してイテレータを作成する場合、reverseを使用して、逆のシーケンスの「最初」を見つけ、必要な要素だけを見て適用できますシーケンス自体の逆です。

考案された例、

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