J'utilise des générateurs pour effectuer des recherches dans des listes comme cet exemple simple:
>>> a = [1,2,3,4]
>>> (i for i, v in enumerate(a) if v == 4).next()
3
(Juste pour encadrer un peu l'exemple, j'utilise des listes beaucoup plus longues par rapport à celle ci-dessus, et les entrées sont un peu plus compliquées que int
. Je le fais de cette façon pour que toutes les listes gagnent ' t être parcouru chaque fois que je les recherche)
Maintenant, si je le changeais plutôt en i == 666
, il retournerait un StopIteration
car il ne peut pas trouver de 666
entrée dans a
.
Comment puis-je le faire retourner None
à la place? Je pourrais bien sûr l'envelopper dans un try ... except
clause, mais existe-t-il une manière plus pythonique de le faire?
Si vous utilisez Python 2.6+, vous devez utiliser la fonction intégrée next
, pas la méthode next
(qui était remplacé par __next__
en 3.x). Le next
intégré prend un argument par défaut facultatif à renvoyer si l'itérateur est épuisé, au lieu d'augmenter StopIteration
:
next((i for i, v in enumerate(a) if i == 666), None)
Vous pouvez chaîner le générateur avec (Aucun,):
from itertools import chain
a = [1,2,3,4]
print chain((i for i, v in enumerate(a) if v == 6), (None,)).next()
mais je pense que a.index (2) ne traversera pas la liste complète, lorsque 2 est trouvé, la recherche est terminée. vous pouvez tester ceci:
>>> timeit.timeit("a.index(0)", "a=range(10)")
0.19335955439601094
>>> timeit.timeit("a.index(99)", "a=range(100)")
2.1938486138533335