11
votes

meilleure syntaxe de boucle pour détecter des séquences vides?

Y a-t-il un meilleur moyen d'écrire ce qui suit:

for item in sequence:
   #process item
*else*:
   #handle the empty sequence case


5 commentaires

Un meilleur moyen de l'écrire - dans quel but?


Pour le rendre plus concis et plus idiomatique. (Je vais ajouter ceci à ma question)


Un orèse pourrait répondre à cela pour vous; Quelque chose comme db-api's .fetchone () ou First () méthodes retour Aucun Si le jeu de résultats est vide (pas de lignes).


Voir Stackoverflow.com/Questtions/1952464/...


Personnellement, je trouve le code d'origine plus lisible et idiomatique que les réponses données. (Une variable de drapeau booléenne is_empty serait également approprié.) @Mtrw: iter ([]) renvoie un itérateur, mais est une séquence vide.


5 Réponses :


8
votes
it = empty_adaptor(some_iter)
if it is not None: 
   for i in it:
       # handle items
else:
   # handle empty case

3 commentaires

J'ai besoin de traiter tous les éléments de la liste, pas seulement le premier. Pour traiter le reste des articles, je devrai configurer une autre boucle, ce qui rendra toute la solution encore moins concise que l'original.


On dirait que la consommation d'un article n'est pas une option pour le O.P. Étant donné que H E doit "faire des choses" avec chaque article.


@DMITRY BERANSKY: Si vous devez consommer tous les éléments, vous pouvez écrire un adaptateur qui accepte une iérente comme entrée et retourne Aucun s'il est vide ou donne la même séquence d'éléments que son entrée. Pour la mise en œuvre, vous pouvez utiliser la variante la plus lisible parmi fournie dans cette question jusqu'à présent.



0
votes
if not iterable_sequence.__length_hint__():
    empty()
else:
    for item in iterable_sequence:
        dostuff()

2 commentaires

Cela déclencherait-il pas un appel à Len ()?


Il déclencherait un appel à LEN () pour des séquences déjà évaluées, ce qui n'est pas un problème - il n'appellerait pas len sur d'autres itérables - car ils n'ont généralement pas de len quand même. Cependant, ces itérables testeront toujours comme true, à moins d'avoir spécialement surchargé cette opération (comme xrange fait).



3
votes

C'est peut-être un travail pour itertools.tee Vous "déclencher" la séquence sur la vérification, mais vous êtes laissé avec une copie intacte de la séquence par la suite: xxx

(il vaut la peine de nuler que TEE est-ce " droite "chose ici: il chargera simplement le premier élément de la séquence dans le moment check.next () est exécuté - et ce premier élit restera disponible dans la séquence . Les articles restants ne seront extraits que dans le cadre de la boucle pour Ou juste le garder simple: Si vous ne pouvez pas utiliser Len, vous ne pouvez pas vérifier si la séquence a une valeur de BOOL de TRUE, pour les mêmes raisons.

Par conséquent, votre chemin est suffisamment simple - Une autre façon serait de supprimer le nom "article" avant la déclaration "pour" et Vérifiez si cela existe après la boucle: xxx

mais votre code doit être utilisé comme plus clair que celui-ci.


2 commentaires

DEL Item SUMPRESSE SUMPRESSEEELREROR Si le nom L'élément n'a pas été défini.


Utilisation de TEE n'est probablement pas la voie à suivre - il va tamponner tous les éléments, attendre vérifier pour être itéré. Pour une longueur finie, une liste peut être plus efficace, pour une longueur infinie itable, elle fuit silencieusement la mémoire. Vérification de NameError est brillant, cependant.



2
votes

Le deuxième exemple de JF Sebastian semble être le ticket avec une boucle tandis que. XXX

Pas le plus concis mais de manière objective la ... boue, non? < / p>


0 commentaires

2
votes

Cela ne devrait pas déclencher len () : xxx


1 commentaires

[10 ans plus tard :-)] C'est la meilleure réponse pour le python moderne.