Jak ustawić dwie pętle for w pythonie do rozumienia list


101

Mam dwie listy, jak poniżej

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

Chcę wpisów wyciąg z entrieskiedy są w tags:

result = []

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

Jak mogę zapisać te dwie pętle jako jedno wierszowe rozumienie listy?


3
Użyj, itertools.chainjeśli chcesz spłaszczoną listę:list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
Ashwini Chaudhary

Odpowiedzi:


135

To powinno wystarczyć:

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

158

Najlepszym sposobem na zapamiętanie tego jest to, że kolejność pętli for wewnątrz rozumienia list jest oparta na kolejności, w jakiej pojawiają się w tradycyjnym podejściu pętlowym. Najpierw pętla zewnętrzna, a następnie pętle wewnętrzne.

Zatem równoważne rozumienie listy wyglądałoby tak:

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

Ogólnie rzecz biorąc, if-elseinstrukcja występuje przed pierwszą pętlą for, a jeśli masz tylko ifinstrukcję, pojawi się na końcu. Na przykład, jeśli chcesz dodać pustą listę, jeśli tagnie ma jej we wpisie, możesz to zrobić w ten sposób:

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

6

Odpowiednie LC byłoby

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

Kolejność pętli w LC jest podobna do tych w zagnieżdżonych pętlach, instrukcje if idą na koniec, a wyrażenia warunkowe na początku, coś w rodzaju

[a if a else b for a in sequence]

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

EDYTUJ - ponieważ potrzebujesz spłaszczenia wyniku, możesz użyć podobnego rozumienia listy, a następnie spłaszczyć wyniki.

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

Dodając to razem, możesz po prostu zrobić

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

Używasz tutaj wyrażenia generatora zamiast rozumienia listy. (Idealnie pasuje również do limitu 79 znaków (bez listwywołania))


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)

Wynik:

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

1
return=[entry for tag in tags for entry in entries if tag in entry for entry in entry]

6
Cześć i witaj w Stack Overflow! Proszę zamieścić wyjaśnienie, a nie tylko kod.
Evelyn

1
Witaj! Chociaż ten kod może rozwiązać problem, w tym wyjaśnienie, jak i dlaczego to rozwiązuje problem, naprawdę pomogłoby poprawić jakość twojego posta i prawdopodobnie zaowocowałoby większą liczbą pozytywnych głosów. Pamiętaj, że odpowiadasz na pytanie do czytelników w przyszłości, a nie tylko osoba, która zapyta teraz. Proszę edytować swoje odpowiedzi, aby dodać wyjaśnień i dać wskazówkę co zastosować ograniczenia i założenia.
Brian

0

Zrozumienie, iteracja zagnieżdżonych list powinna mieć tę samą kolejność, co odpowiednik imbricowany dla pętli.

Aby to zrozumieć, weźmiemy prosty przykład z NLP. Chcesz utworzyć listę wszystkich słów z listy zdań, gdzie każde zdanie jest listą słów.

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

Aby usunąć powtarzające się słowa, możesz użyć zestawu {} zamiast listy []

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

lub aplikuj list(set(all_words))

>>> all_unique_words = list(set(all_words))
['.', 'dog', 'the', 'chases', 'barks', 'mouse', 'The', 'cat']
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.