Возможности Python безграничны. Кажется, что на каждый совет и трюк, который вы изучаете, есть еще дюжина других, которые можно усвоить и использовать, чтобы облегчить жизнь. На мой взгляд, один из самых изящных трюков, который вы можете сделать как питонист, — это вывести понимание списка.

Для тех, кто не знает, понимание списка — это строка кода, которая циклически проходит через итератор (например, список, кортеж или словарь) и выбирает определенные элементы в зависимости от того, соответствует ли элемент некоторым критериям. Результатом является новый список ответов, соответствующих условному выражению.

Например:

first_ten = [1,2,3,4,5,6,7,8,9,10]
evens = [number for number in first_ten if number % 2 == 0]
evens = [2, 4, 6, 8, 10]

Это понимание списка, которое создает новый список чисел на основе того, делится ли каждое число в нашем списке first_ten без остатка на 2.

Другими словами, мы просим python предоставить нам новый список всех чисел из first_ten, где условие истинно. Другой способ написать это:

evens = []
for number in first_ten:
    if number % 2 == 0:
        evens.append(number)

Разница со списком заключается в том, что вы делаете то же самое в одной строке, а не в четырех. Чувствует себя прекрасно, правда?

Вложенные списки

Возможно, вы захотите присесть для следующей части. Подобно тому, как мы вложили условное выражение «if» внутрь цикла «for» для нашей более длинной версии приведенной выше задачи, вы также можете вложить одно понимание списка в другое. Сногсшибательно, верно?

Но когда вам понадобится понимание вложенного списка?

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

address_book = 
     {“Sally”: "[email protected]", 
      “John”: "[email protected]",
      “Veejay”: "[email protected]",  
      “Tom”: "[email protected]", 
      “Meredith”: "[email protected]", 
      “Margot”: "[email protected]}
invite_list = ["John", "Veejay", "Margot"]

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

Это прекрасная возможность для понимания вложенного списка:

invite_emails = [address_book[key] for name in invite_list for key in address_book if name in key]
invite_emails = ["[email protected]", "[email protected]", "[email protected]"]

Понимание списка Python за 3 шага

Итак, мы перебираем список и сверяем каждую запись со словарем, который мы также просматриваем. Подход с вложенным циклом может быть чем-то уродливым, например:

for item in invite_list:
    for key in address_book:
        if item == key:
            return value

Но это вызывает много ошибок и в целом довольно болезненно смотреть на это. Нет-нет, мы должны использовать понимание вложенного списка. Мы можем это сделать (см. выше ответ: мы уже сделали)!

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

Шаг 1. В генераторе списка выполните итерацию по ключам в address_book и заполните новый генератор списка каждым значением в словаре.

invite_emails = [address_book[key] for key in address_book]
invite_emails = ["[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", 
"[email protected]"]

Успех! Мы успешно прошли через наш словарь без сообщений об ошибках. Это хороший первый шаг, но помните, что нам также нужно перебрать список приглашенных.

Шаг 2.Вставьте итерацию в список приглашений.

invite_emails = [address_book[key] for name in invite_list for key in address_book]
invite_emails = ['[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]', '[email protected]']

Ладно, это немного дико. У нас есть три набора электронных писем, хотя в идеале нам нужен только один. Это связано с тем, что мы просим python вернуть ключи для каждого экземпляра элемента в списке_приглашений. Три элемента означают целых три списка адресов электронной почты!

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

Шаг 3. Добавьте условное выражение в конце понимания вложенного списка.

invite_emails = [address_book[key] for name in invite_list for key in address_book if name in key]
invite_emails = ['[email protected]', '[email protected]', '[email protected]']

… и вот оно. Новый список, который заполняет ключи словаря, если они находятся во втором списке. Звучит так просто, когда ты так говоришь, правда? (Неправильный)

В общем, понимание вложенных списков (и обычное понимание списков) довольно удобная и полезная функция Python. Использование их стало моей второй натурой. Они помогают сжать то, что в противном случае было бы сложным многострочным кодом, в одну строку. Что может быть лучше, чем это?!?

Если вы повторяете две разные структуры данных и сравниваете информацию, это будет прекрасной возможностью развернуть этот уникальный фрагмент кода (и произвести впечатление на ваших друзей). Но полезно вспомнить одну из моих любимых цитат о жизни и программировании:

«Планы ничего не стоят, но планирование — это все».

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

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