Как создать два цикла for в понимании списка Python


101

У меня есть два списка, как показано ниже

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

Я хочу извлечь записи, entriesкогда они находятся в tags:

result = []

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

Как я могу написать два цикла как понимание списка одной строки?


3
Используйте, itertools.chainесли хотите сплющенный список:list(chain.from_iterable(entry for tag in tags for entry in entries if tag in entry))
Ашвини Чаудхари

Ответы:


135

Это должно сделать это:

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

159

Лучший способ запомнить это - то, что порядок цикла for внутри понимания списка основан на порядке, в котором они появляются в традиционном подходе цикла. Сначала идет самый внешний цикл, а затем внутренний цикл.

Итак, эквивалентное понимание списка будет:

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

Как правило, if-elseоператор ставится перед первым циклом for, и если у вас есть только ifоператор, он будет в конце. Например, если вы хотите добавить пустой список, если tagего нет в записи, вы должны сделать это следующим образом:

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

6

Соответствующий аккредитив будет

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

Порядок циклов в LC аналогичен порядку циклов во вложенных циклах, операторы if идут в конец, а условные выражения идут в начало, что-то вроде

[a if a else b for a in sequence]

См. Демонстрацию -

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

РЕДАКТИРОВАТЬ. Поскольку вам нужно, чтобы результат был сглаженным, вы можете использовать аналогичное понимание списка, а затем сгладить результаты.

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

Сложив это вместе, вы могли бы просто сделать

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

Здесь вы используете выражение генератора вместо понимания списка. (Также идеально соответствует ограничению в 79 символов (без listвызова))


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)

Вывод:

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

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

6
Привет и добро пожаловать в Stack Overflow! Пожалуйста, разместите объяснение, а не только код.
Эвелин

1
Здравствуйте! Хотя этот код может решить вопрос, в том числе объяснение того, как и почему это решает проблему, действительно поможет улучшить качество вашего сообщения и, вероятно, приведет к большему количеству голосов за. Помните, что вы отвечаете на вопрос для будущих читателей, а не только для человека, который задает его сейчас. Пожалуйста , измените свой ответ , чтобы добавить объяснения и дать указание о том , что применять ограничения и допущения.
Брайан,

0

В понимании, итерация вложенных списков должна следовать в том же порядке, что и эквивалентные циклы for.

Чтобы понять это, мы возьмем простой пример из НЛП. Вы хотите создать список всех слов из списка предложений, где каждое предложение представляет собой список слов.

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

Чтобы удалить повторяющиеся слова, вы можете использовать набор {} вместо списка []

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

или применить list(set(all_words))

>>> all_unique_words = list(set(all_words))
['.', 'dog', 'the', 'chases', 'barks', 'mouse', 'The', 'cat']
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.