Actuellement, je fais ceci:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Mais je voudrais une expression que je puisse placer dans un simple if
déclaration. Y a-t-il quelque chose de intégré qui rendrait ce code moins maladroit?
any()
Retour False
si un itérable est vide, mais il itérera potentiellement sur tous les éléments si ce n'est pas le cas. Je n'en ai besoin que pour vérifier le premier élément.
Quelqu'un demande ce que j'essaye de faire. J'ai écrit une fonction qui exécute une requête SQL et donne ses résultats. Parfois, lorsque j'appelle cette fonction, je veux juste savoir si la requête a renvoyé quelque chose et prendre une décision en fonction de cela.
Réponses:
any
n'ira pas au-delà du premier élément s'il est vrai. Au cas où l'itérateur donnerait quelque chose de faux, vous pouvez écrireany(True for _ in iterator)
.la source
any((x > 100 for x in xrange(10000000)))
puis exécutezany((x > 10000000 for x in xrange(100000000)))
- le second devrait prendre beaucoup plus de temps.sum(1 for _ in itertools.islice(iterator, max_len)) >= max_len
all(False for _ in iterator)
va vérifier si l'itérateur est vide. (all retourne True si l'itérateur est vide, sinon il s'arrête lorsqu'il voit le premier élément False)En Python 2.6+, si le nom
sentinel
est lié à une valeur que l'itérateur ne peut pas fournir,Si vous n'avez aucune idée de ce que l'itérateur pourrait éventuellement produire, créez votre propre sentinelle (par exemple en haut de votre module) avec
Sinon, vous pouvez utiliser, dans le rôle sentinelle, n'importe quelle valeur que vous «connaissez» (en fonction des considérations d'application) que l'itérateur ne peut pas fournir.
la source
if not next(iterator, None):
c'était suffisant car j'étais sûr qu'aucun ne ferait partie des éléments. Merci de m'avoir pointé dans la bonne direction!not
retournera True pour tout objet faux, comme les listes vides, False et zéro.is not None
est plus sûr et à mon avis plus clair.Ce n'est pas vraiment plus propre, mais cela montre un moyen de le regrouper dans une fonction sans perte:
Ce n'est pas vraiment pythonique, et pour des cas particuliers, il existe probablement de meilleures solutions (mais moins générales), comme la prochaine valeur par défaut.
Ce n'est pas général car None peut être un élément valide dans de nombreux itérables.
la source
next()
.tee
in itertools devront conserver chaque élément de l'itérateur d'origine au cas où il seraitany_check
nécessaire d'avancer. C'est pire que de simplement convertir l'itérateur d'origine en liste.vous pouvez utiliser:
mais c'est un peu non explicatif pour le lecteur de code
la source
La meilleure façon de le faire est d'utiliser un
peekable
fichier frommore_itertools
.Méfiez-vous simplement si vous avez conservé les références de l'ancien itérateur, cet itérateur deviendra avancé. Vous devez utiliser le nouvel itérateur visible à partir de là. Vraiment, cependant, peekable s'attend à être le seul morceau de code modifiant cet ancien itérateur, vous ne devriez donc pas garder les références de l'ancien itérateur de toute façon.
la source
Qu'en est-il de:
la source
class NotSet: pass
, puis vérifierif next(i, NotSet) is NotSet: print("Iterator is empty")
__length_hint__
estime la longueur delist(it)
- c'est une méthode privée, cependant:la source
C'est un wrapper d'itérateur excessif qui permet généralement de vérifier s'il y a un élément suivant (via la conversion en booléen). Bien sûr assez inefficace.
Production:
la source
Un peu tard, mais ... Vous pouvez transformer l'itérateur en liste et travailler avec cette liste:
la source