Список Пониманий

Список понимание создает новый list , применяя выражение к каждому элементу Iterable . Наиболее простой формой является:

 [ <expression> for <element> in <iterable> ]

 

Также есть необязательное условие if:

 [ <expression> for <element> in <iterable> if <condition> ]

 

Каждый <element> в <iterable> подключен к <expression> если (необязательно) <condition> оценивается как истина . Все результаты сразу возвращаются в новый список. Генератор выражение вычисляется лениво, но списочные оценить весь итератор сразу - потребляя память , пропорциональную длину итератора.

Для того, чтобы создать list квадратов целых чисел:

 squares = [x * x for x in (1, 2, 3, 4)]
# squares: [1, 4, 9, 16]

 

for выражения устанавливает x для каждого значения в свою очередь , из (1, 2, 3, 4) . Результат выражения x * x добавляются к внутреннему list . Внутренний list присваиваются переменными squares , когда завершено.

Помимо увеличения скорости (как описано здесь ), список понимание примерно эквивалентно следующее для цикла:

 squares = []
for x in (1, 2, 3, 4):
    squares.append(x * x)
# squares: [1, 4, 9, 16]

 

Выражение, применяемое к каждому элементу, может быть настолько сложным, насколько это необходимо:

 # Get a list of uppercase characters from a string
[s.upper() for s in "Hello World"]
# ['H', 'E', 'L', 'L', 'O', ' ', 'W', 'O', 'R', 'L', 'D']

# Strip off any commas from the end of strings in a list
[w.strip(',') for w in ['these,', 'words,,', 'mostly', 'have,commas,']]
# ['these', 'words', 'mostly', 'have,commas']

# Organize letters in words more reasonably - in an alphabetical order
sentence = "Beautiful is better than ugly"
["".join(sorted(word, key = lambda x: x.lower())) for word in sentence.split()]
# ['aBefiltuu', 'is', 'beertt', 'ahnt', 'gluy']

 

еще

else может быть использован в списке понимание конструкций, но быть осторожными в отношении синтаксиса. Если / иначе пункты должны быть использованы до for цикла, а не после того, как :

 # create a list of characters in apple, replacing non vowels with '*'
# Ex - 'apple' --> ['a', '*', '*', '*' ,'e']

[x for x in 'apple' if x in 'aeiou' else '*']
#SyntaxError: invalid syntax

# When using if/else together use them before the loop
[x if x in 'aeiou' else '*' for x in 'apple']
#['a', '*', '*', '*', 'e']

 

Обратите внимание , это использует различные конструкции языка, а условное выражение , которое само по себе не является частью синтаксиса понимания . В то время как , if после того , как for…in это часть списковых и используются для фильтрации элементов из источника итерации.

Двойная итерация

Порядок двойной итерации [... for x in ... for y in ...] является естественным или нелогичным. Правило заключается в том , чтобы следовать эквивалент for цикла:

 def foo(i):
    return i, i + 0.5

for i in range(3):
    for x in foo(i):
        yield str(x)

 

Это становится:

 [str(x)
    for i in range(3)
        for x in foo(i)
]

 

Это может быть сжат в одну линию , как [str(x) for i in range(3) for x in foo(i)]

Мутация на месте и другие побочные эффекты

Перед использованием списка понимания, понять разницу между функциями , вызываемыми для их побочных эффектов (Mutating, или в месте функции) , которые , как правило , не возвращают None , и функции , которые возвращают интересное значение.

Многие функции (особенно чистые функции) просто взять объект и вернуть какой - то объект. Функция в месте изменяет существующий объект, который называется побочным эффектом. Другие примеры включают операции ввода и вывода, такие как печать.

list.sort() сортирует список на месте ( это означает , что он изменяет первоначальный список) и не возвращает значение None . Следовательно, он не будет работать так, как ожидалось при понимании списка:

 [x.sort() for x in [[2, 1], [4, 3], [0, 1]]]
# [None, None, None]

 

Вместо sorted() возвращает отсортированный list , а не сортировку на месте:

 [sorted(x) for x in [[2, 1], [4, 3], [0, 1]]]
# [[1, 2], [3, 4], [0, 1]]

 

Возможно использование понимания побочных эффектов, таких как ввод / вывод или функции на месте. Тем не менее цикл for обычно более читабелен. Пока это работает в Python 3:

 [print(x) for x in (1, 2, 3)]

 

Вместо этого используйте:

 for x in (1, 2, 3):
    print(x)

 

В некоторых ситуациях, побочные функции эффекта подходят для списка понимания. random.randrange() имеет побочный эффект изменения состояния генератора случайных чисел, но она также возвращает интересное значение. Кроме того, в next() может быть вызван итератора.

Следующий генератор случайных значений не является чистым, но имеет смысл, поскольку генератор случайных значений сбрасывается каждый раз, когда вычисляется выражение:

 from random import randrange
[randrange(1, 7) for _ in range(10)]
# [2, 3, 2, 1, 1, 5, 2, 4, 3, 5]

 

Пробелы в списках

Более сложные списки могут достигать нежелательной длины или становиться менее читабельными. Хотя это не так часто встречается в примерах, можно разбить понимание списка на несколько строк следующим образом:

 [
    x for x
    in 'foo'
    if x not in 'bar'
]