So rahmen Sie zwei for-Schleifen in Python für das Listenverständnis ein


101

Ich habe zwei Listen wie unten

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

Ich möchte Einträge extrahieren, aus entriesdenen sie stammen tags:

result = []

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

Wie kann ich die beiden Schleifen als einzeiliges Listenverständnis schreiben?


3
Verwenden itertools.chainSie, wenn Sie eine abgeflachte Liste wünschen:list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
Ashwini Chaudhary

Antworten:


135

Dies sollte es tun:

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

155

Der beste Weg, sich daran zu erinnern, ist, dass die Reihenfolge der for-Schleife innerhalb des Listenverständnisses auf der Reihenfolge basiert, in der sie im traditionellen Schleifenansatz erscheinen. Die äußerste Schleife kommt zuerst und dann die innere Schleife anschließend.

Das äquivalente Listenverständnis wäre also:

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

Im Allgemeinen steht die if-elseAnweisung vor der ersten for-Schleife, und wenn Sie nur eine ifAnweisung haben, wird sie am Ende stehen. Wenn Sie beispielsweise eine leere Liste hinzufügen möchten, wenn diese tagnicht im Eintrag enthalten ist, gehen Sie folgendermaßen vor:

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

6

Der passende LC wäre

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

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

[a if a else b for a in sequence]

Siehe die 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 reduziert 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']

Wenn Sie dies zusammenzählen, können Sie es 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 hier einen Generatorausdruck anstelle eines Listenverständnisses. (Passt auch perfekt zum Limit von 79 Zeichen (ohne listAnruf))


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)

Ausgabe:

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

0

Zum Verständnis sollte die Iteration verschachtelter Listen in derselben Reihenfolge erfolgen wie das für Schleifen imäplierte Äquivalent.

Zum Verständnis nehmen wir ein einfaches Beispiel aus NLP. Sie möchten eine Liste aller Wörter aus einer Liste von Sätzen erstellen, wobei jeder Satz eine Liste von Wörtern ist.

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

Um die wiederholten Wörter zu entfernen, können Sie eine Menge {} anstelle einer Liste [] verwenden.

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

oder bewerben 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
Hallo und willkommen bei Stack Overflow! Bitte posten Sie eine Erklärung und nicht nur Code.
Evelyn vor

1
Hallo! Während dieser Code die Frage lösen kann, einschließlich einer Erklärung, wie und warum dies das Problem löst, würde dies wirklich dazu beitragen, die Qualität Ihres Beitrags zu verbessern, und wahrscheinlich zu mehr Up-Votes führen. Denken Sie daran, dass Sie in Zukunft die Frage für die Leser beantworten, nicht nur für die Person, die jetzt fragt. Bitte bearbeiten Sie Ihre Antwort, um Erklärungen hinzuzufügen und anzugeben, welche Einschränkungen und Annahmen gelten.
Brian vor
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.