Actuellement, je fais ceci:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Mais je voudrais une expression que je puisse placer dans une simple instruction if
. Y a-t-il quelque chose de intégré qui rendrait ce code moins maladroit?
any()
renvoie False
si un itérable est vide, mais il peut potentiellement parcourir tous les éléments s'il ne l'est pas. J'en ai seulement besoin pour vérifier le premier article.
Quelqu'un me demande ce que j'essaie 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 simplement savoir si la requête a renvoyé quelque chose et prendre une décision en fonction de cela.
any
ne dépassera pas le premier élément s'il est vrai. Dans le cas où l'itérateur renvoie quelque chose de faux, vous pouvez écrire any(True for _ in iterator)
.
Dans Python 2.6+, si le nom sentinel
est lié à une valeur que l'itérateur ne peut éventuellement pas fournir,
if next(iterator, sentinel) is sentinel:
print('iterator was empty')
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
sentinel = object()
Sinon, vous pourriez utiliser, dans le rôle de sentinelle, toute valeur que vous "connaissez" (sur la base de considérations d'application) que l'itérateur ne peut éventuellement pas fournir.
Ce n'est pas vraiment plus propre, mais cela montre un moyen de l'intégrer dans une fonction sans perte:
def has_elements(iter):
from itertools import tee
iter, any_check = tee(iter)
try:
any_check.next()
return True, iter
except StopIteration:
return False, iter
has_el, iter = has_elements(iter)
if has_el:
# not empty
Ce n'est pas vraiment Pythonic, et pour des cas particuliers, il existe probablement de meilleures solutions (mais moins générales), comme le suivant par défaut.
first = next(iter, None)
if first:
# Do something
Ce n'est pas général car None peut être un élément valide dans de nombreux itérables.
vous pouvez utiliser:
if Zip([None], iterator):
# ...
else:
# ...
mais c'est un peu non explicatif pour le lecteur de code
Qu'en est-il de:
In [1]: i=iter([])
In [2]: bool(next(i,False))
Out[2]: False
In [3]: i=iter([1])
In [4]: bool(next(i,False))
Out[4]: True