Понимание списочных представлений в Python 3

Вступление

List comprehensions предлагает краткий способ созданияlists на основе существующих списков. При использовании понимания списков списки могут быть построены с использованием любыхiterable, включаяstrings иtuples.

Синтаксически списки состоят из итерации, содержащей выражение, за которым следует предложениеfor. За этим могут следовать дополнительные предложенияfor илиif, поэтому знакомство сfor loops иconditional statements поможет вам лучше понять смысл списка.

Компоненты списков предоставляют альтернативный синтаксис созданию списков и других последовательныхdata types. В то время как другие методы итерации, такие как циклыfor, также могут использоваться для создания списков, понимание списков может быть предпочтительным, поскольку оно может ограничивать количество строк, используемых в вашей программе.

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

В Python списки понимаются так:

list_variable = [x for x in iterable]

Список, или другой итерируемый, присваивается переменной. Дополнительные переменные, которые обозначают элементы в итерируемом объекте, создаются вокруг предложенияfor. Ключевое словоin используется, как и в циклахfor, для перебораiterable.

Давайте рассмотрим пример, который создает список на основе строки:

shark_letters = [letter for letter in 'shark']
print(shark_letters)

Здесь новый список присваивается переменнойshark_letters, аletter используется для замены элементов, содержащихся в повторяемой строке'shark'.

Чтобы подтвердить, как выглядит новый списокshark_letters, мы вызываем его вprint() и получаем следующий вывод:

Output['s', 'h', 'a', 'r', 'k']

Список, который мы создали с пониманием списка, состоит из элементов в строке'shark', то есть по одной строке для каждой буквы.

Компоненты списка можно переписать как циклыfor, хотя не каждый циклfor можно переписать как понимание списка.

Используя наше понимание списка, которое создало списокshark_letters выше, давайте перепишем его как циклfor. Это может помочь нам лучше понять, как работает понимание списка.

shark_letters = []

for letter in 'shark':
    shark_letters.append(letter)

print(shark_letters)

При создании списка с помощью циклаfor переменная, назначенная списку, должна быть инициализирована пустым списком, как это находится в первой строке нашего блока кода. Затем циклfor выполняет итерацию по элементу, используя переменнуюletter в повторяемой строке'shark'. В циклеfor каждый элемент в строке равенadded to the list with the list.append(x) method.

Переписав понимание списка в виде циклаfor, мы получим тот же результат:

Output['s', 'h', 'a', 'r', 'k']

Компоненты списков могут быть переписаны как циклыfor, а некоторые циклыfor могут быть переписаны в виде списков, чтобы сделать код более лаконичным.

Использование условных выражений со списками

При составлении списков можно использовать условные операторы для изменения существующих списков или других последовательных типов данных при создании новых списков.

Давайте посмотрим на пример оператораif, используемого в понимании списка:

fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')

fish_list = [fish for fish in fish_tuple if fish != 'octopus']
print(fish_list)

Понимание списка использует кортежfish_tuple как основу для нового списка под названиемfish_list. Ключевые словаfor иin используются, как и вsection above, а теперь добавлен операторif. Операторif говорит, что нужно добавлять только те элементы, которые не эквивалентны строке'octopus', поэтому новый список принимает только элементы из кортежа, которые не соответствуют'octopus'.

Когда мы запустим это, мы увидим, чтоfish_list содержит те же строковые элементы, что иfish_tuple, за исключением того факта, что строка'octopus' была опущена:

Output['blowfish', 'clownfish', 'catfish']

Поэтому в нашем новом списке есть каждый элемент исходного кортежа, кроме строки, которая исключена условным оператором.

Мы создадим еще один пример, который используетmathematical operators,integers иrange() sequence type.

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

Создаваемый списокnumber_list будет заполнен квадратами значений каждого элемента в диапазоне от 0 до 9if, значение элемента делится на 2. Вывод следующий:

Output[0, 4, 16, 36, 64]

Чтобы еще немного разобраться в том, что делает список, давайте подумаем о том, что было бы напечатано, если бы мы просто вызывалиx for x in range(10). Наша маленькая программа и выходные данные будут выглядеть так:

number_list = [x for x in range(10)]
print(number_list)
Output[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Теперь давайте добавим условное утверждение:

number_list = [x for x in range(10) if x % 2 == 0]
print(number_list)
Output[0, 2, 4, 6, 8]

Операторif ограничил элементы в окончательном списке, чтобы включить только те элементы, которые делятся на 2, исключая все нечетные числа.

Наконец, мы можем добавить оператор для возведения в квадрат каждогоx:

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

Итак, каждое из чисел в предыдущем списке[0, 2, 4, 6, 8] теперь возведено в квадрат:

Output[0, 4, 16, 36, 64]

Вы также можете скопироватьnested if statements с пониманием списка:

number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(number_list)

Здесь составление списка сначала проверяет, делится ли числоx на 3, а затем проверяет, делится лиx на 5. Еслиx удовлетворяет обоим требованиям, он будет напечатан, и на выходе будет:

Output[0, 15, 30, 45, 60, 75, 90]

Условные операторыif могут использоваться для управления тем, какие элементы из существующей последовательности включаются в создание нового списка.

Вложенные циклы в понимании списка

Nested loops можно использовать для выполнения нескольких итераций в наших программах.

На этот раз мы рассмотрим существующую конструкцию вложенного циклаfor и перейдем к пониманию списка.

Наш код создаст новый список, который повторяет более 2 списков и выполняет математические операции на их основе. Вот наш вложенный блок кода циклаfor:

my_list = []

for x in [20, 40, 60]:
    for y in [2, 4, 6]:
        my_list.append(x * y)

print(my_list)

Когда мы запускаем этот код, мы получаем следующий вывод:

Output[40, 80, 120, 80, 160, 240, 120, 240, 360]

Этот код умножает элементы в первом списке на элементы во втором списке на каждой итерации.

Чтобы преобразовать это в понимание списка, мы сжимаем каждую из строк кода в одну строку, начиная с операцииx * y. За этим последует внешний циклfor, затем внутренний циклfor. Мы добавим операторprint() под нашим пониманием списка, чтобы подтвердить, что новый список соответствует списку, который мы создали с помощью нашего вложенного блока циклаfor выше:

my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
print(my_list)
Output[40, 80, 120, 80, 160, 240, 120, 240, 360]

Наше понимание списков берет вложенные циклыfor и объединяет их в одну строку кода, создавая при этом тот же самый список для назначения переменнойmy_list.

Постижения списков предоставляют нам краткий способ составления списков, позволяя нам разделить несколько строк кода в одну строку. Однако стоит помнить, что удобочитаемость нашего кода всегда должна иметь приоритет, поэтому, когда строка понимания списка становится слишком длинной или громоздкой, может быть лучше разбить ее на циклы.

Заключение

Понимание списка позволяет нам преобразовать один или другой список в новый список. Они предоставляют краткий синтаксис для выполнения этой задачи, ограничивая наши строки кода.

Постижения списков следуют математической форме нотации конструктора множеств или понимания множеств, поэтому они могут быть особенно интуитивными для программистов с математическим прошлым.

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