Преобразование в циклы for и наоборот

Те из нас, кто преодолел отметку новичка в изучении Python, могли столкнуться с пониманием списков, которое, по сути, является более коротким и элегантным способом создания списка с использованием цикла for.
Понимание списка в двух словах
Допустим, у нас уже есть существующий список фруктов:
fruits = ["apple", "orange", "pear"]
Вот основное понимание списка:
lis = [fruit for fruit in fruits] # lis will ["apple", "orange", "pear"]
Это то же самое, что:
lis = []
for fruit in fruits:
lis.append(fruit)
# lis will ["apple", "orange", "pear"]
Оба блока кода дают нам точную копию нашего списка fruits.
Изменение элементов в понимании списка
Иногда мы не просто хотим, чтобы элемент был передан нам циклом for — мы можем захотеть каким-то образом его видоизменить. Например, возможно, вместо самих фруктов нам нужна длина названий фруктов — "apple" состоит из 5 букв, "orange" из 6 букв и "pear" из 4 букв, поэтому наш результирующий список должен быть [5, 6, 4].
lis = []
for fruit in fruits:
lis.append(len(fruit))
# lis will be [5, 6, 4]
Мы также можем сделать это в одной строке, используя понимание списка:
lis = [len(fruit) for fruit in fruits] # lis will be [5, 6, 4]
Давайте сравним это с нашим базовым пониманием списка [fruit for fruit in fruits]. Обратите внимание, что мы заменяем первую fruit на len(fruit). Здесь мы, по сути, сообщаем Python, что вместо названий фруктов нам нужна длина имен фруктов в нашем результирующем списке.
Операторы if-else в понимании списка
Предположим, теперь мы хотим сопоставить плоды длины 5 с "yes", а плоды всех остальных длин с "no". Поскольку только "apple" имеет длину 5, наш результирующий список должен быть ["yes", "no", "no"]. Вот как мы могли бы сделать это, используя цикл for:
lis = []
for fruit in fruits:
if len(fruit) == 5:
lis.append("yes")
else:
lis.append("no")
# lis will be ["yes", "no", "no"]
И вот эквивалентный способ сделать это, используя понимание списка:
lis = ["yes" if len(fruit)==5 else "no" for fruit in fruits] # lis will be ["yes", "no", "no"]
Давайте сравним это с нашим базовым пониманием списка [fruit for fruit in fruits]. Обратите внимание, что мы заменяем первое fruit на "yes" if len(fruit)==5 else "no". Это известно как тернарный оператор в Python и по сути является оператором if-else, сжатым в 1 строку — он принимает значение "yes", если len(fruit)==5, и "no" в противном случае.
Выбор только определенных элементов в понимании списка
Иногда мы не хотим, чтобы каждый элемент исходного списка отображался в результирующем списке. Допустим, нам нужны только плоды длиной 5 и выше. Здесь мы ожидаем, что наш результирующий список будет содержать только "apple" и "orange", а не "pear", поскольку "pear" имеет только 4 буквы. Вот как мы могли бы сделать это, используя обычный цикл for.
lis = []
for fruit in fruits:
if len(fruit) >= 5:
lis.append(fruit)
# lis will be ["apple", "orange"]
Вот как мы делаем это, используя понимание списка:
lis = [fruit for fruit in fruits if len(fruit)>=5] # lis will be ["apple", "orange"]
Давайте сравним это с нашим базовым пониманием списка [fruit for fruit in fruits]. Обратите внимание, что мы добавляем условие if len(fruit)>=5 сзади посленашего исходного списка fruits. При этом будут вставлены только те элементы, которые удовлетворяют условию, в данном случае это "apple" и "orange", поскольку они имеют длину не менее 5.
Понимание списка с вложенными циклами for
Иногда нам нужно иметь дело с вложенными циклами for. Например, допустим, у нас теперь есть 2 списка:
fruits = ["apple", "orange", "pear"] recipes = ["pie", "juice"]
И мы хотим, чтобы каждое сочетание фруктов и рецептов:
# the resultant list we want result = ["applepie", "applejuice", "orangepie", "orangejuice", "pearpie", "pearjuice"]
Вот как мы могли бы сделать это, используя вложенный цикл for:
lis = []
for f in fruits:
for r in recipes:
lis.append(f+r)
А вот эквивалент понимания списка:
lis = [f+r for f in fruits for r in recipes]
Обратите внимание, что здесь есть дополнительный цикл for после for f in fruits — чтобы преобразовать вложенный цикл for в понимание списка, нам просто нужно написать циклы for один за другим, начиная с самого внешнего цикла for. Например, предположим, что у нас есть вложенный цикл for:
lis = []
for f in fruits:
for r in recipes:
for s in sugar_levels:
lis.append(f + r + s)
Чтобы преобразовать это в понимание списка, нам просто нужно соединить все циклы for вместе for f in fruits for r in recipes for s in sugar_levels. Обратите внимание, что нам нужно начать с самого внешнего цикла for for f in fruits и продвигаться вниз.
Заключение
Надеюсь, это было полезно. Если это было полезно для вас и вы хотите поддержать меня как писателя, подумайте о том, чтобы подписаться на членство в Medium! Это 5 долларов в месяц, и вы получаете неограниченный доступ к историям на Medium. Если вы зарегистрируетесь по моей ссылке, я получу небольшую комиссию.
Вот ссылка для чтения неограниченного доступа к Medium
Если вы находите ценность в том, что читаете, и хотите получать уведомления всякий раз, когда я публикую статью, рассмотрите возможность подписки на мою рассылку.
Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку здесь.