2013-08-31 5 views
44

Ich habe zwei Listen, wie untenWie zwei for-Schleifen in Liste Verständnis Python Frame

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

Ich möchte Einträge aus entries extrahieren, wenn sie in tags sind:

result = [] 

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

Wie kann ich schreiben die zwei Schleifen als eine einzige Zeile Liste Verständnis?

+2

Verwenden 'itertools.chain', wenn Sie eine abgeflachte Liste wollen:' Liste (Ketten .from_iterable (Eintrag für Tag in Tags für Eintrag in Einträgen, wenn Tag im Eintrag)) ' –

Antwort

57

Dies sollte es tun:

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

Die entsprechende LC würde

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

Die Reihenfolge der Schleifen in der LC sein zu den in verschachtelten Schleifen ähnlich ist, gehen die if-Anweisungen bis zum Ende und die bedingten Ausdrücke gehen am Anfang, etwas wie

[a if a else b for a in sequence] 

Siehe Demo -

>>> 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']] 

BEARBEITEN - Da das Ergebnis geglättet werden muss, können Sie ein ähnliches Listenverständnis verwenden und dann die Ergebnisse reduzieren.

>>> 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'] 

diese zusammen Hinzufügen, könnten Sie einfach tun

>>> 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'] 

Sie verwenden einen Generator Ausdruck hier statt einer Liste Verständnis. (Passend zu den 79 Zeichen begrenzt zu (ohne list Aufruf))

76

Der beste Weg, dies zu erinnern ist, dass die Reihenfolge der for-Schleife in der Liste Verständnis basiert in der Reihenfolge, in der sie im traditionellen Schleifenansatz erscheinen. Die äußerste Schleife kommt zuerst und dann die inneren Schleifen nacheinander.

Also, das äquivalente Liste Verständnis wäre:

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

Im Allgemeinen if-else Aussage kommt vor dem ersten for-Schleife, und wenn Sie nur eine if Aussage haben, wird es am Ende kommen. Für zB, wenn Sie eine leere Liste hinzufügen möchten, wenn tag nicht in Eintritt ist, würden Sie es wie folgt tun:

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