Преобразование в циклы 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. Подпишитесь на нашу бесплатную еженедельную рассылку здесь.