Share This
Связаться со мной
Крути в низ
Categories
//Цикл for в Python: тонкости написания

Цикл for в Python: тонкости написания

31.07.2021Category : Python

Цикл for — одна из базовых управляющих конструкций в любом языке программирования. Простейший цикл в языке Си выглядит так:

int i; for (i=0;i<N;i++) {   // действия }

В Си нет более элегантного способа написать цикл for. В более сложных сценариях мы обычно прибегаем к вложенным циклам и множеству вспомогательных переменных (например, i в примере выше).

К счастью, в Python все намного удобнее. У этого языка есть возможности, позволяющие писать лаконичные циклы — это очень упрощает нашу жизнь. В Python можно избежать вложенных циклов, а вспомогательные переменные объявлять вовсе не обязательно. А еще мы сами можем настроить цикл for!

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

Выводим индекс и значение одновременно

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

for i in range(len(my_list)):     print(i, my_list[i])

Да, это работает. Но это недостаточно «питонично». Через несколько месяцев изучения Python я решал эту задачу так:

for i, v in enumerate(my_list):     print(i, v)

Как видите, встроенная функция enumerate значительно упрощает нашу жизнь. 

Избавляемся от вложенных циклов с помощью функции product 

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

К счастью, существует очень полезная встроенная функция — product. Она является частью встроенного модуля Python — itertools. С ее помощью мы можем избавиться от вложенных циклов. 

Рассмотрим пример:

list_a = [1, 2020, 70] list_b = [2, 4, 7, 2000] list_c = [3, 70, 7]  for a in list_a:     for b in list_b:         for c in list_c:             if a + b + c == 2077:                 print(a, b, c) # 70 2000 7

Объявлено три списка чисел. Нам нужно вывести три числа (по одному из каждого списка), сумма которых равна 2077. Чтобы решить эту задачу, нам понадобилось три вложенных цикла. Код выглядит совсем не изящно. 

А теперь опробуем функцию product.

from itertools import product  list_a = [1, 2020, 70] list_b = [2, 4, 7, 2000] list_c = [3, 70, 7]  for a, b, c in product(list_a, list_b, list_c):     if a + b + c == 2077:         print(a, b, c)  # 70 2000 7

Как видите, с помощью функции product количество циклов сокращается до одного. 

Функция product возвращает декартово произведение входных итераторов. Благодаря этому мы можем избежать написания вложенных циклов во многих сценариях.

Используем модуль Itertools для написания невероятных циклов

Функция product — лишь вершина айсберга. Изучение модуля itertools сравнимо с открытием нового мира. В нем содержится множество полезных методов, которые могут упростить любой цикл. Полный список вы можете найти в официальной документации. 

Рассмотрим несколько примеров. 

Создаем бесконечный цикл

В модуле itertools есть как минимум три метода для создания бесконечных циклов: 

1. Функция count.

natural_num = itertools.count(1) for n in natural_num:     print(n)  # 1,2,3,...

2. Функция cycle.

import itertools  many_yang = itertools.cycle('Hello') for y in many_yang:     print(y)  # 'H','e','l','l','o','H','e','l',...

3. Функция repeat.

many_yang = itertools.repeat('Hello') for y in many_yang:     print(y)  # 'Hello','Hello',...

Объединяем несколько итераторов в один

Функция chain() помогает нам объединять несколько итераторов в один.

from itertools import chain  list_a = [1, 22] list_b = [7, 20] list_c = [3, 70]  for i in chain(list_a, list_b, list_c):     print(i)  # 1,22,7,20,3,70

Выводим повторяющиеся элементы и количество их повторений

Функция groupby() позволяет получить повторяющиеся элементы в итераторе и сгруппировать их. 

from itertools import groupby  for key, group in groupby('Pyttthhhonissst'):     print(key, list(group))  # P ['P'] # y ['y'] # t ['t', 't', 't'] # h ['h', 'h', 'h'] # o ['o'] # n ['n'] # i ['i'] # s ['s', 's', 's'] # t ['t']

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

from itertools import groupby  for key, group in groupby('PyYyYTTthHOoOnisst', lambda x: x.upper()):     print(key, list(group))  # P ['P'] # Y ['y', 'Y', 'y', 'Y'] # T ['T', 'T', 't'] # H ['h', 'H'] # O ['O', 'o', 'O'] # N ['n'] # I ['i'] # S ['s', 's'] # T ['t']

Самостоятельно настраиваем цикл for

После ознакомления с примерами пора наконец разобраться, почему же циклы в Python такие гибкие и изящные. Этими своими свойствами они обязаны тому, что к итератору в цикле for можно применять функции. Во всех примерах, приведенных выше, к итераторам применялась какая-нибудь функция. Шаблон в целом выглядит так:

for x in function(iterator)

То есть, суть itertools проста — этот модуль применяет часто используемые функции к итератору. Если вы забыли какую-либо функцию из itertools — реализуйте ее самостоятельно. Также стоит заметить, что все эти функции — генераторы. Вот почему с их помощью мы можем создавать бесконечные циклы. 

Таким образом, написав генератор, вы можете настроить цикл for так, как вам необходимо. 

Рассмотрим простой пример:

def even_only(num):     for i in num:         if i % 2 == 0:             yield i   my_list = [1, 9, 3, 4, 2, 5] for n in even_only(my_list):     print(n) # 4 # 2

Как видите, мы объявляем генератор — even_only. Если мы встроим этот генератор в цикл, то итерация будет происходить только по четным элементам списка. 

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

my_list = [1, 9, 3, 4, 2, 5] for n in (i for i in my_list if not i % 2):     print(n) # 4 # 2

Вывод

Циклы в Python могут быть изящны и гибки. Такими их делают встроенные функции и генераторы. 

cikl for v python tonkosti napisanija 48f6588 - Цикл for в Python: тонкости написания

Кодинг-марафон по Python

Реши 10 задач и выиграй 5500 рублей

Подписаться ×

  • 5 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close