12
votes

Obtenez une première chaîne non vide dans une liste de Python

Dans Python, j'ai une liste de cordes, dont certaines peuvent être la chaîne vide. Quelle est la meilleure façon d'obtenir la première chaîne non vide?


3 commentaires

Voulez-vous la référence à la première chaîne vide ou souhaitez-vous supprimer toutes les chaînes vides d'une liste? Cette liste a-t-elle été générée d'une chaîne fractionnée par hasard?


Généré à partir de regex: allumettes = re.findall (r "foo (\ d +) | bar (\ d +)") - Je veux la première chaîne non vide, mais serait intéressé par la manière de supprimer toutes les cordes vides (la regex pourrait devenir plus long).


Le titre de votre question ne correspond pas au corps de votre question. Réparer l'un d'entre eux.


6 Réponses :


6
votes

Pour enlever toutes les cordes vides,

[s pour s dans list_of_strings si s]

Pour obtenir la première chaîne non vide, créez simplement cette liste et obtenez le premier élément, ou utilisez la méthode paresseuse comme suggérée par Wuub.


1 commentaires

Un peu inefficace, cependant! Si vous avez un million de piqûres non vides après juste un jeu vide, vous passerez du temps et de la mémoire générant une liste d'un million de chaîne, uniquement pour obtenir le premier ... au moins, utilisez un générateur!



3
votes
def get_nonempty(list_of_strings):
    for s in list_of_strings:
        if s:
            return s

2 commentaires

Loin moins élégant que la compréhension génératrice suggérée ci-dessus ajoute plus de complexité au fichier source.


Élégance dans les yeux du spectateur, Daniel. Cela fonctionne parfaitement, contrairement à la version de la réponse acceptée: c'est ce qui compte



25
votes
next(s for s in list_of_string if s)
Edit: py3k proof version as advised by Stephan202 in comments, thanks. 

8 commentaires

[] est appelé compréhension de la liste.


PY3K Version: Suivant (S pour S dans list_of_string si s) .


Je reçois une erreur (voir ci-dessous) avec la version PY3K, mais .NEXT () fonctionne. NomError: Nom global 'Suivant' n'est pas défini


@Fred, la prochaine a été faite intégrée en 2.6


@Fred: En effet, cela fonctionne depuis 2,6. Dans Python 2.5 et avant, vous devrez utiliser (...). Suivant () .


BTW, ça va augmenter stopiteration si toutes les chaînes sont vides.


@Fred: Tout est vraiment déroutant: le prochain (générateur) fonctionne en 2.6 et 3.x; générateur .__ Next __ () fonctionne dans 3.x; Generator.Next () fonctionne dans 2.x


Pour éviter de traiter avec un stopiteration , la version à deux arguments de suivant () peut être utilisé pour spécifier une valeur de secours: suivant ((S pour S dans list_of_strings si s)," non trouvé ")



0
votes

Pour obtenir la première chaîne non vide dans une liste, il vous suffit de la boucler et de vérifier si ce n'est pas vide. C'est tout ce qu'il y a.

arr = ['','',2,"one"]
for i in arr:
    if i:
        print i
        break


0 commentaires

3
votes

Voici une courte façon:

from itertools import ifilter
ifilter(None, list_of_strings).next()


6 commentaires

Pourquoi la deuxième voie est-elle meilleure?


Cela ne fonctionne que dans Python 2.x, et est moins efficace que l'exemple générateur, car filtre iTère sur toute la liste, quel que soit le contenu. Dans PY3K Filtre renvoie un objet de filtrage, qui est irrégulier.


@Fred: La première voie passera à travers chaque chaîne vide, créez une nouvelle liste et sélectionnez le premier résultat. La deuxième méthode passera à travers la liste filtrant des chaînes vides jusqu'à ce qu'il trouve le premier vide et le retournera. Aucune liste intermédiaire ne serait créée. Par exemple, si vous avez une liste de 10 000 chaînes et que seul le premier est vide, la première méthode crée une nouvelle liste de 9 999 chaînes en mémoire, tandis que la seconde ne le fait pas.


@ Stephan202: La "voie légèrement plus longue" équivaut à l'exemple générateur, je pense.


+1 pour une réponse qui fonctionne dans Python 2.x et 1.5.2 :-) - Malheureusement pas en 3.x


@Steve. En effet. L'équivalent PY3K est suivant (filtre (aucun, list_of_strings) . (Aucune importation requise.)



0
votes

Basé sur votre question, je devrai supposer beaucoup, mais "Obtenir" la première chaîne non vide: xxx

qui renvoie son index dans la liste. Les points de liaison «X» sur votre liste de chaînes.


0 commentaires