Comment encadrer deux boucles for en python de compréhension de liste


101

J'ai deux listes comme ci-dessous

tags = [u'man', u'you', u'are', u'awesome']
entries = [[u'man', u'thats'],[ u'right',u'awesome']]

Je souhaite extraire les entrées de entriesleur emplacement tags:

result = []

for tag in tags:
    for entry in entries:
        if tag in entry:
            result.extend(entry)

Comment puis-je écrire les deux boucles en une seule ligne de compréhension de liste?


3
À utiliser itertools.chainsi vous voulez une liste aplatie:list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
Ashwini Chaudhary

Réponses:


135

Cela devrait le faire:

[entry for tag in tags for entry in entries if tag in entry]

157

La meilleure façon de s'en souvenir est que l'ordre des boucles for à l'intérieur de la compréhension de la liste est basé sur l'ordre dans lequel elles apparaissent dans l'approche de boucle traditionnelle. La boucle la plus externe vient en premier, puis les boucles internes par la suite.

Ainsi, la compréhension de liste équivalente serait:

[entry for tag in tags for entry in entries if tag in entry]

En général, l' if-elseinstruction vient avant la première boucle for, et si vous n'avez qu'une ifinstruction, elle viendra à la fin. Par exemple, si vous souhaitez ajouter une liste vide, si elle tagn'est pas dans l'entrée, vous le feriez comme ceci:

[entry if tag in entry else [] for tag in tags for entry in entries]

6

Le LC approprié serait

[entry for tag in tags for entry in entries if tag in entry]

L'ordre des boucles dans le LC est similaire à ceux des boucles imbriquées, les instructions if vont à la fin et les expressions conditionnelles vont au début, quelque chose comme

[a if a else b for a in sequence]

Voir la démo -

>>> tags = [u'man', u'you', u'are', u'awesome']
>>> entries = [[u'man', u'thats'],[ u'right',u'awesome']]
>>> [entry for tag in tags for entry in entries if tag in entry]
[[u'man', u'thats'], [u'right', u'awesome']]
>>> result = []
    for tag in tags:
        for entry in entries:
            if tag in entry:
                result.append(entry)


>>> result
[[u'man', u'thats'], [u'right', u'awesome']]

MODIFIER - Puisque vous avez besoin que le résultat soit aplati, vous pouvez utiliser une compréhension de liste similaire, puis aplatir les résultats.

>>> result = [entry for tag in tags for entry in entries if tag in entry]
>>> from itertools import chain
>>> list(chain.from_iterable(result))
[u'man', u'thats', u'right', u'awesome']

En ajoutant cela ensemble, vous pouvez simplement faire

>>> list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
[u'man', u'thats', u'right', u'awesome']

Vous utilisez ici une expression de générateur au lieu d'une compréhension de liste. (Correspond parfaitement à la limite de 79 caractères aussi (sans l' listappel))


2
tags = [u'man', u'you', u'are', u'awesome']
entries = [[u'man', u'thats'],[ u'right',u'awesome']]

result = []
[result.extend(entry) for tag in tags for entry in entries if tag in entry]

print(result)

Production:

['man', 'thats', 'right', 'awesome']

0

En compréhension, l'itération des listes imbriquées doit suivre le même ordre que l'équivalent imbriqué pour les boucles.

Pour comprendre, nous prendrons un exemple simple de la PNL. Vous souhaitez créer une liste de tous les mots à partir d'une liste de phrases où chaque phrase est une liste de mots.

>>> list_of_sentences = [['The','cat','chases', 'the', 'mouse','.'],['The','dog','barks','.']]
>>> all_words = [word for sentence in list_of_sentences for word in sentence]
>>> all_words
['The', 'cat', 'chases', 'the', 'mouse', '.', 'The', 'dog', 'barks', '.']

Pour supprimer les mots répétés, vous pouvez utiliser un ensemble {} au lieu d'une liste []

>>> all_unique_words = list({word for sentence in list_of_sentences for word in sentence}]
>>> all_unique_words
['.', 'dog', 'the', 'chase', 'barks', 'mouse', 'The', 'cat']

ou postuler list(set(all_words))

>>> all_unique_words = list(set(all_words))
['.', 'dog', 'the', 'chases', 'barks', 'mouse', 'The', 'cat']

0
return=[entry for tag in tags for entry in entries if tag in entry for entry in entry]

6
Bonjour et bienvenue dans Stack Overflow! Veuillez poster une explication et pas seulement un code.
Evelyn

1
salut! Bien que ce code puisse résoudre la question, inclure une explication sur comment et pourquoi cela résout le problème aiderait vraiment à améliorer la qualité de votre publication et entraînerait probablement plus de votes à la hausse. N'oubliez pas que vous répondez à la question des lecteurs à l'avenir, pas seulement à la personne qui la pose maintenant. Veuillez modifier votre réponse pour ajouter des explications et donner une indication des limites et des hypothèses applicables.
Brian
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.