Python 2.6のイテレータから最後のアイテムを取得する最良の方法は何ですか?たとえば、
my_iter = iter(range(5))
4
からmy_iter
を取得する最短コード/最もクリーンな方法は何ですか?
私はこれを行うことができましたが、それは非常に効率的ではないようです:
[x for x in my_iter][-1]
item = defaultvalue
for item in my_iter:
pass
サイズ1の deque
を使用します。
from collections import deque
#aa is an interator
aa = iter('Apple')
dd = deque(aa, maxlen=1)
last_element = dd.pop()
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()
おそらく__reversed__
利用可能な場合
if hasattr(my_iter,'__reversed__'):
last = next(reversed(my_iter))
else:
for last in my_iter:
pass
単純な:
max(enumerate(the_iter))[1]
これは、ラムダのために空のforループよりも高速ではありませんが、おそらく他の誰かにアイデアを与えるでしょう
reduce(lambda x,y:y,my_iter)
Iterが空の場合、TypeErrorが発生します
これがあります
list( the_iter )[-1]
反復の長さが本当に壮大な場合、つまりリストの実体化がメモリを使い果たすほど長い場合、設計を再考する必要があります。
reversed
を使用しますが、イテレータではなくシーケンスのみを使用することを除いて、これはかなりarbitrary意的です。
いずれにしても、イテレーター全体を実行する必要があります。最大限の効率で、イテレーターを再び必要としない場合、すべての値を破棄することができます。
for last in my_iter:
pass
# last is now the last item
しかし、これは次善の解決策だと思います。
toolz ライブラリは素晴らしいソリューションを提供します:
from toolz.itertoolz import last
last(values)
ただし、コア以外の依存関係を追加しても、この場合にのみ使用する価値はありません。
同様のコードについては、このコードをご覧ください:
http://excamera.com/sphinx/article-islast.html
あなたはそれを使って最後のアイテムを拾うことができます:
[(last, e) for (last, e) in islast(the_iter) if last]
私はnext(reversed(myiter))
を使用します
無限イテレータの代わりに、次を使用できます:
from itertools import islice
last = list(islice(iterator(), 1000))[-1] # where 1000 is number of samples
私はそれがdeque
より遅いだろうと思ったが、それは同じくらい速く、実際にはforループ方法よりも速い(どういうわけか)
問題は、イテレータの最後の要素を取得することですが、シーケンスに条件を適用してイテレータを作成する場合、reverseを使用して、逆のシーケンスの「最初」を見つけ、必要な要素だけを見て適用できますシーケンス自体の逆です。
考案された例、
>>> seq = list(range(10))
>>> last_even = next(_ for _ in reversed(seq) if _ % 2 == 0)
>>> last_even
8