Question

Quelle est la meilleure façon d'obtenir le dernier élément d'un iterator en Python 2.6? Par exemple, disons

my_iter = iter(range(5))

Quel est le plus court code / manière la plus propre d'obtenir 4 de my_iter?

Je pourrais le faire, mais il ne semble pas très efficace:

[x for x in my_iter][-1]
Était-ce utile?

La solution

item = defaultvalue
for item in my_iter:
    pass

Autres conseils

Utilisez un deque de taille 1.

from collections import deque

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

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

Si vous utilisez 3.x python:

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

si vous utilisez Python 2.7:

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


NB:

En général, la solution présentée ci-dessus est ce dont vous avez besoin pour les cas réguliers, mais si vous faites affaire avec une grande quantité de données, il est plus efficace d'utiliser un deque de taille 1. ( la source )

from collections import deque

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

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

Probablement la peine d'utiliser __reversed__ si elle est disponible

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

Aussi simple que:

max(enumerate(the_iter))[1]

Il est peu probable d'être plus rapide que le vide pour la boucle en raison du lambda, mais peut-être cela donnera une idée de quelqu'un d'autre

reduce(lambda x,y:y,my_iter)

Si le iter est vide, un TypeError est élevé

Il y a cette

list( the_iter )[-1]

Si la longueur de l'itération est vraiment épique - si longtemps que matérialisant la liste mémoire d'échappement -. Alors vous avez vraiment besoin de repenser la conception

J'utiliser reversed, sauf qu'il ne prend des séquences au lieu de itérateurs, qui semble plutôt arbitraire.

De toute façon vous le faites, vous aurez à courir à travers l'ensemble iterator. À un maximum d'efficacité, si vous n'avez pas besoin iterator jamais, vous pouvez simplement poubelle toutes les valeurs:

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

Je pense que c'est une solution sous-optimale, cependant.

Le toolz bibliothèque offre une belle solution:

from toolz.itertoolz import last
last(values)

Mais l'ajout d'une dépendance non-core peut-être pas la peine pour l'utiliser seulement dans ce cas.

Voir ce code pour quelque chose de semblable:

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

vous pouvez l'utiliser pour ramasser le dernier élément avec:

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

Je voudrais simplement utiliser next(reversed(myiter))

La question est sur le point d'obtenir le dernier élément d'un itérateur, mais si votre iterator est créé en appliquant des conditions à une séquence, puis inversée peut être utilisé pour trouver la « première » d'une séquence inversée, ne regardant que les éléments nécessaires , par application inverse de la séquence elle-même.

Un exemple artificiel,

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

Sinon, pour itérateurs infini vous pouvez utiliser:

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

Je pensais que ce serait plus lent que deque mais il est aussi rapide et il est en fait plus rapide que pour la méthode de la boucle (en quelque sorte)

La question est erronée et ne peut conduire à une réponse qui est complexe et inefficace. Pour obtenir un itérateur, bien sûr, vous commencez à partir de quelque chose qui est itératives, qui dans la plupart des cas offrir une façon plus directe d'accéder au dernier élément.

Une fois que vous créez un itérateur d'un itérables vous êtes coincé dans passant par les éléments, parce que c'est la seule chose qu'un itérables fournit.

Ainsi, la façon la plus claire et efficace est de ne pas créer l'itérateur en premier lieu, mais d'utiliser les méthodes d'accès natif du itérables.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top