Come inquadrare due cicli for in Python di comprensione delle liste


101

Ho due elenchi come di seguito

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

Voglio estrarre le voci da entriesquando sono in tags:

result = []

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

Come posso scrivere i due cicli come una sola riga di comprensione dell'elenco?


3
Utilizzare itertools.chainse si desidera un elenco appiattito:list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
Ashwini Chaudhary

Risposte:


135

Questo dovrebbe farlo:

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

157

Il modo migliore per ricordarlo è che l'ordine del ciclo for all'interno della comprensione della lista si basa sull'ordine in cui appaiono nell'approccio tradizionale del ciclo. Viene prima il ciclo più esterno e successivamente quello interno.

Quindi, la comprensione dell'elenco equivalente sarebbe:

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

In generale, l' if-elseistruzione viene prima del primo ciclo for, e se hai solo ifun'istruzione, arriverà alla fine. Ad esempio, se desideri aggiungere un elenco vuoto, se tagnon è in entrata, lo faresti in questo modo:

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

6

La LC appropriata sarebbe

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

L'ordine dei cicli in LC è simile a quelli dei cicli annidati, le istruzioni if ​​vanno alla fine e le espressioni condizionali vanno all'inizio, qualcosa di simile

[a if a else b for a in sequence]

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

MODIFICA - Poiché è necessario che il risultato venga appiattito, è possibile utilizzare una comprensione dell'elenco simile e quindi appiattire i risultati.

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

Aggiungendo questo insieme, potresti semplicemente farlo

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

Usa un'espressione del generatore qui invece di una comprensione dell'elenco. (Corrisponde perfettamente anche al limite di 79 caratteri (senza la listchiamata))


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)

Produzione:

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

0

In termini di comprensione, l'iterazione degli elenchi annidati dovrebbe seguire lo stesso ordine dell'equivalente imbricato per i cicli.

Per capire, prenderemo un semplice esempio dalla PNL. Vuoi creare un elenco di tutte le parole da un elenco di frasi in cui ogni frase è un elenco di parole.

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

Per rimuovere le parole ripetute, puoi utilizzare un insieme {} invece di un elenco []

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

o applicare 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
Ciao e benvenuto in Stack Overflow! Si prega di pubblicare una spiegazione e non solo un codice.
Evelyn

1
Ciao! Sebbene questo codice possa risolvere la domanda, inclusa una spiegazione di come e perché questo risolve il problema aiuterebbe davvero a migliorare la qualità del tuo post e probabilmente si tradurrebbe in più voti positivi. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo alla persona che chiede ora. Si prega di modificare la risposta per aggiungere spiegazioni e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni.
Brian
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.