web-dev-qa-db-fra.com

Comment encadrer deux des boucles en compréhension de liste 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 les entrées de entries quand elles 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 compréhension d'une seule ligne?

76

Cela devrait le faire:

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

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

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

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

En général, if-else déclaration vient avant la première boucle for, et si vous avez juste une instruction if, elle viendra à la fin. Par exemple, si vous souhaitez ajouter une liste vide, si tag ne figure pas dans l'entrée, procédez comme suit:

[entry if tag in entry else [] for tag in tags for entry in entries]
123
Rohit Jain

Le nombre approprié LC serait

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

L'ordre des boucles dans le 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 - Étant donné que vous avez besoin d'aplatir le résultat, 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 pourriez 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 génératrice au lieu d’une compréhension de liste. (Correspond parfaitement à la limite de 79 caractères aussi (sans l'appel list.))

5
Sukrit Kalra
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']
2
Raghav Gupta