162 votes

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

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 veux extraire des entrées de entries lorsqu'ils sont dans tags :

result = []

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

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

246voto

Rohit Jain Points 90368

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 traditionnelle des boucles. La boucle la plus extérieure vient en premier, puis les boucles intérieures par la suite.

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

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

En général, if-else se trouve avant la première boucle for, et si vous avez juste une instruction if déclaration, elle viendra à la fin. Par exemple, si vous souhaitez ajouter une liste vide, si tag n'est pas en entrée, vous le feriez comme ceci :

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

195voto

Cela devrait le faire :

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

9voto

Sukrit Kalra Points 11349

Le CL approprié serait

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

L'ordre des boucles dans la LC est similaire à celui 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']]

EDIT - Puisque vous avez besoin que le résultat soit aplati, vous pouvez utiliser une compréhension de liste similaire et aplatir ensuite 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 additionnant tout ça, vous pourriez juste 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. (Cela correspond aussi parfaitement à la limite de 79 caractères (sans l'élément list appel))

7voto

HommeDeJava Points 46

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

Pour comprendre, nous allons prendre un exemple simple tiré de la PNL. Vous voulez 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 appliquer list(set(all_words))

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

2voto

Raghav Gupta Points 117
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)

Sortie :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X