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?
Cela devrait le faire:
[entry for tag in tags for entry in entries if tag in entry]
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]
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
.))
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']