Циклы “while” и “for” в Python

25 мая, 2020

Подписывайся на наш канал в Telegram, чтобы ежедневно совершенствоваться в Python - перейти

Оглавление

  • Цикл While
    • о цикле
    • Прерывание и продолжение
    • Else
    • Бесконечные циклы
    • Вложенные циклы
    • Однолинейные циклы
    • Вывод
  • Цикл For
    • Обзор определенной итерации в программировании
      • Цикл числового диапазона
      • Цикл с тремя выражениями
      • Цикл на основе коллекции или итератора
    • Python цикл For
      • Итерируемые объекты
      • Итераторы
    • Под капотом
    • Перебор словаря
    • Функция range()
    • Изменение поведения цикла
      • break и continue
      • else
    • Вывод

Итерация означает выполнение одного и того же блока кода снова и снова, потенциально много раз. Структура программирования, которая реализует итерацию, называется циклом.

В программировании существует два типа итераций: неопределенный и определенный:

  • При неопределенной итерации (while) число выполнений цикла заранее не указывается явно. Скорее, назначенный блок выполняется многократно, пока выполняется некоторое условие.
  • При определенной итерации (for) число раз, когда указанный блок будет выполнен, указывается явно во время запуска цикла.

Цикл while

В этом блоке про while:

  • Узнаете о while цикле, структуре управления Python используемой для неопределенной итерации
  • Посмотрите, как преждевременно выйти из цикла
  • Исследуете цикл

Давайте посмотрим, как  while используется для создания циклов. Мы начнем с простого.

Формат элементарного while цикла показан ниже:

while <expr>:
    <statement(s)>

<statement(s)> представляет собой блок для многократного выполнения, часто называемый телом цикла. Обозначается с отступом, как в if заявлении.

Помните: все управляющие структуры в Python используют отступы для определения блоков.

Управляющее выражение – <expr> как правило, включает в себя одну или несколько переменных, которые инициализируются до начала цикла, а затем изменяются где-то в теле цикла.

Когда встречается while цикл, <expr> сначала оценивается в логическом контексте . Если это правда, тело цикла выполняется. Затем <expr> проверяется снова, и если все еще true, то выполняется снова. Это продолжается до тех пор, пока <expr> станет false, после чего выполнение программы переходит к первому оператору после тела цикла.

Рассмотрим этот цикл:

n = 5
while n > 0:
    n -= 1
    print(n)

Вот что происходит в этом примере:

  • n изначально равно 5. Выражение в while заголовке оператора n > 0 имеет значение true, поэтому тело цикла выполняется. Внутри тела цикла n уменьшается на 1 до 4 и затем печатается.
  • Когда тело цикла завершено, выполнение программы возвращается к началу цикла, и выражение проверяется снова. Оно все еще true, поэтому тело выполняется снова и 3 печатается.
  • Это продолжается до тех пор, пока не n станет 0. В этот момент, когда выражение проверяется, оно ложно, и цикл завершается.

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

n = 0
while n > 0:
    n -= 1
    print(n)

В приведенном выше примере, когда встречается цикл, n равно 0. Управляющее выражение n > 0 уже ложно, поэтому тело цикла никогда не выполнится.

Вот еще один while цикл, включающий список, а не числовое сравнение:

a = ['foo', 'bar', 'baz']
while a:
    print(a.pop(-1))

Когда список оценивается в логическом контексте , true если в нем есть элементы, и false если он пустой. В этом примере a это правда, в нем есть элементы. Как только все элементы были удалены с помощью .pop() метода и список пуст, цикл завершается.

 break и continue

В каждом примере, который вы видели до этого, все тело while цикла выполняется на каждой итерации. Python предоставляет два ключевых слова, которые преждевременно завершают итерацию цикла:

  • Оператор break немедленно завершает цикл полностью. Выполнение программы продолжается до первого оператора, следующего за телом цикла.
  • Инструкция continue немедленно завершает текущую итерацию цикла. В основном используется для пропуска итерации, или переходу к следующей итерации.

Различие между break и continueпоказано на следующей диаграмме:

Циклы Python while: операторы break и continue
перерыв и продолжить

Вот файл сценария с именем break.py который демонстрирует break утверждение:

n = 5
while n > 0:
    n -= 1
    if n == 2:
        break
    print(n)
print('Loop ended.')

Запуск break.py из интерпретатора командной строки приводит к следующему выводу:

C:\Users\pythonguru\Documents>python break.py
4
3
Loop ended.

Когда n становится 2break заявление выполняется, цикл полностью завершается, и выполнение программы переходит к print() оператору.

Следующий скрипт continue.py идентичен, за исключением continue оператора вместо break:

n = 5
while n > 0:
    n -= 1
    if n == 2:
        continue
    print(n)
print('Loop ended.')

Вывод continue.py:

C:\Users\pythonguru\Documents>python continue.py
4
3
1
0
Loop ended.

На этот раз, когда n равно 2continue оператор вызывает завершение этой итерации. Таким образом, 2 не печатается. Выполнение возвращается к началу цикла, условие переоценивается, и оно все еще выполняется. Цикл возобновляется, завершается, когда n становится 0, как ранее.

else

Python допускает необязательное else в конце while цикла. Это уникальная особенность Python, не встречающаяся в большинстве других языков программирования. Синтаксис показан ниже:

while <expr>:
    <statement(s)>
else:
    <additional_statement(s)>

<additional_statement(s)> указанный в else пункте, будет выполняться , когда прервётся цикл while .

мысленный шар

Сейчас вы можете подумать: «Как это полезно?». Вы можете сделать то же самое, поместив эти операторы сразу после while цикла, без else:

while <expr>:
    <statement(s)>
<additional_statement(s)>

Какая разница?

В последнем случае, без else<additional_statement(s)> будет выполняться после завершения while цикла, несмотря ни на что.

Когда <additional_statement(s)> помещены в else, они будут выполняться только в том случае, если цикл завершается «по истощению», то есть, если цикл повторяется до тех пор, пока условие управления не станет ложным. Если цикл завершается break оператором, else предложение не будет выполнено.

Рассмотрим следующий пример:

n = 5
while n > 0:
    n -= 1
    print(n)
else:
    print('Loop done.')

В этом случае цикл повторялся до тех пор, пока условие не было false: n стало 0, а условие n > 0 стало ложным. Поскольку цикл прожил свою естественную жизнь, так сказать, else пункт был выполнен. Теперь обратите внимание на разницу здесь:

n = 5
while n > 0:
    n -= 1
    print(n)
    if n == 2:
        break
else:
    print('Loop done.')

Этот цикл преждевременно завершается с помощью break, поэтому else не выполняется.

Может показаться, что значение слова else не совсем соответствует while циклу, а также if выражению. Гвидо ван Россум (Guido van Rossum) , создатель Python, на самом деле сказал, что, если бы ему пришлось повторить, он бы исключил else цикла while   из языка.

Одна из следующих интерпретаций может помочь сделать ее более интуитивной:

  • Думайте о заголовке цикла (while n > 0) как об if операторе (if n > 0), который выполняется снова и снова, и else выполняется, когда условие становится false.

Если вы не найдете ни одну из этих интерпретаций полезной, не стесняйтесь игнорировать их.

Когда может быть полезным else в whileцикле? Одна распространенная ситуация, если вы ищете в списке определенный элемент. Вы можете использовать break для выхода из цикла, если элемент найден, и else может содержать код, который должен быть выполнен, если элемент не найден:

a = ['foo', 'bar', 'baz', 'qux']
s = 'corge'

i = 0
while i < len(a):
    if a[i] == s:
        # Processing for item found
        break
    i += 1
else:
    # Processing for item not found
    print(s, 'not found in list.')

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

Прежде всего, списки обычно обрабатываются с определенной итерацией, а не while циклом. Определенная итерация (for) рассматривается в следующем блоке.

Во-вторых, Python предоставляет встроенные способы поиска элемента в списке. Вы можете использовать in оператор:

if s in a:
    print(s, 'found in list.')
else:
    print(s, 'not found in list.')

list.index() метод также будет работать. Этот метод вызывает ValueError исключение, если элемент не найден в списке, поэтому для его использования необходимо понимать обработку исключений. В Python вы используете try оператор для обработки исключения. Пример приведен ниже:

try:
    print(a.index('corge'))
except ValueError:
    print(s, 'not found in list.')

Вы узнаете об обработке исключений позже.

Бесконечные циклы

Предположим, вы пишете while цикл, который теоретически никогда не заканчивается. Звучит странно, правда?

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

while True:
    print('foo')










KeyboardInterrupt

Этот код был завершен знаком Ctrl+C , который генерирует прерывание с клавиатуры. Иначе это продолжалось бы бесконечно. 

Очевидно, True никогда не будет ложным, или у нас у всех очень большие проблемы. Таким образом, while True: инициирует бесконечный цикл, который теоретически будет работать вечно.

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

Говоря более прозаично, помните, что while можно закончить используя break. Может быть более простым завершить цикл на основе условий, распознанных в теле цикла, а не на условии, оцененном сверху.

Вот еще один вариант показанного выше цикла, который последовательно удаляет элементы из списка, .pop() пока он не станет пустым:>>>

a = ['foo', 'bar', 'baz']
while True:
    if not a:
        break
    print(a.pop(-1))

Когда a становится пустым, not a становится истинным, и break оператор выходит из цикла.

Вы также можете указать несколько break операторов в цикле:

while True:
    if <expr1>:  # One condition for loop termination
        break
    ...
    if <expr2>:  # Another termination condition
        break
    ...
    if <expr3>:  # Yet another
        break

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

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

Вложенные циклы while

В общем, управляющие структуры Python могут быть вложены друг в друга. Например, условные операторы if/elif/else могут быть вложенными:

if age < 18:
    if gender == 'M':
        print('son')
    else:
        print('daughter')
elif age >= 18 and age < 65:
    if gender == 'M':
        print('father')
    else:
        print('mother')
else:
    if gender == 'M':
        print('grandfather')
    else:
        print('grandmother')

Точно так же while цикл может содержаться в другом while цикле, как показано здесь:

a = ['foo', 'bar']
while len(a):
    print(a.pop(0))
    b = ['baz', 'qux']
    while len(b):
        print('>', b.pop(0))

Кроме того, while циклы могут быть вложены в if/elif/else операторы, и наоборот:

if <expr>:
    statement
    while <expr>:
        statement
        statement
else:
    while <expr>:
        statement
        statement
    statement
while <expr>:
    if <expr>:
        statement
    elif <expr>:
        statement
    else:
        statement

    if <expr>:
        statement

Фактически, все управляющие структуры Python могут смешиваться друг с другом в любой степени, в которой вы нуждаетесь. Так и должно быть. Представьте, как это было бы неприятно, если бы были неожиданные ограничения, такие как «whileцикл не может быть заключен в if оператор» или «while циклы могут быть вложены друг в друга не более чем на четыре глубины». Вам было бы очень трудно помнить все.

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

Однолинейные циклы while

Как и в if операторе, while цикл может быть указан в одной строке. Если в блоке, составляющем тело цикла, есть несколько операторов, они могут быть разделены точкой с запятой (;):

n = 5
while n > 0: n -= 1; print(n)

Это работает только с простыми утверждениями, хотя, вы не можете объединить два составных оператора в одну строку. Таким образом, вы можете указать while цикл в одной строке, как указано выше, как вы и пишете if оператор в одной строке:>>>

if True: print('foo')

Но вы не можете сделать это:

while n > 0: n -= 1; if True: print('foo')

Помните, что PEP 8 препятствует нескольким утверждениям в одной строке. Так что, вероятно, вам все равно не следует делать это очень часто.

Вывод

В этом блоке вы узнали о неопределенной итерации с помощью цикла Python while. Теперь вы можете:

  • Построить основные и сложные while циклы
  • Выполнение цикла с break иcontinue
  • Использование else с whileциклом
  • Разбираться с бесконечными циклами

Теперь вы должны хорошо понимать, как выполнять фрагмент кода повторно.

Следующий блок из этого руководства посвящен определенной итерации с for циклами – повторяющимся выполнением, где число повторений указано явно.


Цикл for

Этот блок покажет вам, как выполнить определенную итерацию с for циклом Python .

В предыдущем блоке этой вы узнали следующее:

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

Вот что вы узнаете в этом блоке:

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

Обзор определенной итерации в программировании

Определенные итерационные циклы часто называют for циклами, потому что for это ключевое слово, которое используется для их представления почти на всех языках программирования, включая Python.

Исторически языки программирования предлагали несколько разных вариантов for цикла. Они кратко описаны в следующих разделах.

Цикл числового диапазона

Самый простой for цикл – это простой числовой оператор диапазона с начальными и конечными значениями. Точный формат зависит от языка, но обычно выглядит примерно так:

for i = 1 to 10
    <loop body>

Здесь тело цикла выполняется десять раз. Переменная i принимает значение 1 на первой итерации, 2 на второй и т. д. Этот вид for цикла используется в языках BASIC, Algol и Pascal.

Цикл с тремя выражениями

Другая форма for цикла, популярная на языке программирования C, состоит из трех частей:

  • Инициализация
  • Выражение, указывающее конечное условие
  • Действие, которое нужно выполнить в конце каждой итерации.

Этот тип цикла имеет следующую форму:

for (i = 1; i <= 10; i++)
    <loop body>

Техническое примечание: на языке программирования C i++ увеличивает значение переменной i. Это примерно эквивалентно i += 1 в Python.

Этот цикл интерпретируется следующим образом:

  • Инициализировать i в 1.
  • Продолжать цикл до тех пор, пока i <= 10.
  • Увеличение i на 1 после каждой итерации цикла.

Циклы for с тремя выражениями популярны, потому что выражения, указанные для этих трех частей, могут быть почти любыми, поэтому это имеет немного большую гибкость, чем простая форма числового диапазона, показанная выше. Эти for циклы также представлены в языках C ++, Java, PHP и Perl.

Цикл на основе коллекции или итератора

Этот тип цикла перебирает коллекцию объектов, а не указывает числовые значения или условия:

for i in <collection>
    <loop body>

Каждый раз в цикле переменная i принимает значение следующего объекта в <collection>. Этот тип for цикла, пожалуй, наиболее обобщенный и абстрактный. Perl и PHP также поддерживают этот тип цикла, но он вводится ключевым словом foreach вместо for.

О цикле for

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

Вскоре вы подробно разберетесь в цикле for . Но сейчас давайте начнем с быстрого прототипа и примера, просто чтобы познакомиться.

Цикл for в Python выглядит так:

for <var> in <iterable>:
    <statement(s)>

<iterable> – это коллекция объектов, например, список или кортеж. <statement(s)> в теле цикла обозначаются отступом, как и со всеми структурами управления Python и выполняются один раз для каждого элемента <iterable>. Переменная цикла <var> принимает значение следующего элемента в <iterable> каждый раз в цикле.

Вот типичный пример:

a = ['foo', 'bar', 'baz']
for i in a:
    print(i)

В этом примере <iterable> это список a, а <var> переменная i. Каждый раз через цикл, i берет последовательный элемент в a, так что print()отображает значения 'foo''bar' и 'baz', соответственно.

Но что именно повторяется? Перед for дальнейшим изучением циклов будет полезно более подробно изучить, что же такое итерации в Python.

Итерируемые объекты

В Python повторяемость означает, что объект может использоваться в итерации. Термин используется как:

  • Прилагательное: объект может быть описан как итеративный.
  • Существительное: объект может быть охарактеризован как итеративный.

Если объект является итеративным, его можно передать во встроенную функцию Python iter(), которая возвращает то, что называется итератором . Да, терминология становится немного повторяющейся. Все это работает в конце.

Каждый из объектов в следующем примере является итеративным и возвращает некоторый тип итератора при передаче в iter():

iter('foobar')                             # String


iter(['foo', 'bar', 'baz'])                # List


iter(('foo', 'bar', 'baz'))                # Tuple


iter({'foo', 'bar', 'baz'})                # Set


iter({'foo': 1, 'bar': 2, 'baz': 3})       # Dict

Эти типы объектов, с другой стороны, не повторяемы:>>>

iter(42)                                   # Integer

    


iter(3.1)                                  # Float

    


iter(len)                                  # Built-in function

Типы коллекций или контейнеров, являются итеративными. К ним относятся типы string , list , tuple , dict , set и frozenset .

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

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

Итераторы

Хорошо, теперь вы знаете, что значит для объекта быть итеративным, и вы знаете, как использовать его iter() для получения итератора. Если у вас есть итератор, что вы можете с ним сделать?

Итератор по сути является источником значений, который выдает последовательные значения из своего связанного итерируемого объекта. Встроенная функция next() используется для получения следующего значения в итераторе.

Вот пример, использующий тот же список, что и выше:>>>

a = ['foo', 'bar', 'baz']

itr = iter(a)
itr


next(itr)

next(itr)

next(itr)

В этом примере a это итеративный список, а itrсвязанный с ним итератор, полученный с помощью iter(). Каждый next(itr) вызов получает следующее значение от itr.

Обратите внимание, как итератор внутренне сохраняет свое состояние. Он знает, какие значения уже получены, поэтому при вызове next() он знает, какое значение будет возвращено следующим.

Что происходит, когда у итератора заканчиваются значения? Давайте сделаем еще один next()вызов итератора выше:

>>> next(itr)
Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    next(itr)
StopIteration

Если все значения из итератора уже возвращены, последующий next() вызов вызывает StopIteration исключение. Любые дальнейшие попытки получить значения от итератора потерпят неудачу.

Вы можете получить значения от итератора только в одном направлении. Вы не можете возвращаться назад. Там нет prev() функции. Но вы можете определить два независимых итератора для одного и того же итерируемого объекта:

>>> a
['foo', 'bar', 'baz']

>>> itr1 = iter(a)
>>> itr2 = iter(a)

>>> next(itr1)
'foo'
>>> next(itr1)
'bar'
>>> next(itr1)
'baz'

>>> next(itr2)
'foo'

Даже когда итератор itr1 уже находится в конце списка, itr2 все еще находится в начале. Каждый итератор поддерживает свое собственное внутреннее состояние, независимое от другого.

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

>>> a = ['foo', 'bar', 'baz']
>>> itr = iter(a)
>>> list(itr)
['foo', 'bar', 'baz']

Аналогично, встроенные функции tuple() и set() функции возвращают кортеж и набор соответственно из всех значений, которые дает итератор:

>>> a = ['foo', 'bar', 'baz']

>>> itr = iter(a)
>>> tuple(itr)
('foo', 'bar', 'baz')

>>> itr = iter(a)
>>> set(itr)
{'baz', 'foo', 'bar'}

Не обязательно делать это постоянно. Часть элегантности итераторов в том, что они «ленивы». Это означает, что когда вы создаете итератор, он не генерирует все элементы, которые он может получить. Он ждет, пока вы не попросите их –  next(). Элементы не создаются, пока они не будут запрошены.

При использовании list()tuple() или тому подобное, вы заставляете итератор генерировать все свои значения сразу, поэтому все они могут быть возвращены. Если общее количество объектов, возвращаемых итератором, очень велико, то это может занять много времени.

Фактически в Python можно создать итератор, который возвращает бесконечный ряд объектов. Если вы попытаетесь получить все значения сразу из бесконечного итератора, программа зависнет .

Под капотом for

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

СрокСмысл
ИтерацияПроцесс зацикливания объектов или предметов в коллекции
Итерирумеый объектОбъект (или прилагательное, использованное для описания объекта), который можно повторять
ИтераторОбъект, который производит последовательные элементы или значения из связанных с ним итераций
iter()Встроенная функция, используемая для получения итератора из итерируемого

Теперь снова рассмотрим простой for цикл, представленный в начале этого урока:

a = ['foo', 'bar', 'baz']
for i in a:
    print(i)

Этот цикл может быть полностью описан в терминах концепций, о которых вы только что узнали. Чтобы выполнить итерацию, for описанную в этом цикле, Python делает следующее:

  • Призывает iter() чтобы получить итератор для a
  • Вызывает next() повторно, чтобы получить каждый элемент от итератора по очереди
  • Завершает цикл, когда next() поднимает StopIteration исключение

Тело цикла выполняется один раз для каждого элемента next() возврата,  с переменной цикла i , установленной для данного элемента для каждой итерации.

Эта последовательность событий представлена ​​на следующей диаграмме:

Python для круговой диаграммы
Принципиальная схема питона для цикла

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

  • Многие встроенные и библиотечные объекты являются итеративными.
  • Существует модуль стандартной библиотеки под названием itertools, он содержит много функций, которые возвращают итерации.
  • Пользовательские объекты, созданные с объектно-ориентированной возможностью, могут быть итеративными.
  • Python имеет конструкцию, называемую генератором, которая позволяет вам создать свой собственный итератор простым и понятным способом.

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

Перебор словаря

Ранее вы видели, что итератор может быть получен из словаря iter(), поэтому вы знаете, что словари должны быть итеративными. Что происходит, когда вы перебираете словарь? Посмотрим:

>>> d = {'foo': 1, 'bar': 2, 'baz': 3}
>>> for k in d:
...     print(k)
...
foo
bar
baz

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

Чтобы получить доступ к значениям словаря в цикле, вы можете сделать ссылку на словарь, используя ключ, как обычно:

>>> for k in d:
...     print(d[k])
...
1
2
3

Вы также можете перебирать значения словаря напрямую, используя .values():

>>> for v in d.values():
...     print(v)
...
1
2
3

Фактически, вы можете перебирать и ключи, и значения словаря одновременно. Это потому, что переменная цикла for цикла не ограничивается только одной переменной. Это также может быть кортеж, и в этом случае назначения производятся из элементов итерируемого с использованием packing и unpacking, так же как и с помощью оператора присваивания:

>>> i, j = (1, 2)
>>> print(i, j)
1 2

>>> for i, j in [(1, 2), (3, 4), (5, 6)]:
...     print(i, j)
...
1 2
3 4
5 6

Метод словаря .items() эффективно возвращает список пар ключ / значение в виде кортежей:

>>> d = {'foo': 1, 'bar': 2, 'baz': 3}

>>> d.items()
dict_items([('foo', 1), ('bar', 2), ('baz', 3)])

Таким образом, Pythonic способ перебирать словарь с доступом к ключам и значениям выглядит следующим образом:

>>> d = {'foo': 1, 'bar': 2, 'baz': 3}
>>> for k, v in d.items():
...     print('k =', k, ', v =', v)
...
k = foo , v = 1
k = bar , v = 2
k = baz , v = 3

Функция range()

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

Например, если вы хотите перебрать значения из 0 в 4, вы можете просто сделать это:

>>> for n in (0, 1, 2, 3, 4):
...     print(n)
...
0
1
2
3
4

Это решение не так уж плохо, когда всего несколько цифр. Но если бы диапазон номеров был намного больше, он бы быстро стал утомительным.

К счастью, Python предоставляет лучший вариант – встроенную range() функцию, которая возвращает итерацию, которая дает последовательность целых чисел.

range(<end>) возвращает итерацию, которая дает целые числа, начиная с 0, но не включая <end>:

>>> x = range(5)
>>> x
range(0, 5)
>>> type(x)
<class 'range'>

Обратите внимание, что range() возвращает объект класса range, а не список или кортеж значений. Поскольку range объект является итеративным, вы можете получить значения, повторяя их с помощью for цикла:

>>> for n in x:
...     print(n)
...
0
1
2
3
4

Вы также можете получить все значения сразу с помощью list() или tuple(). В сеансе REPL это может быть удобным способом быстрого отображения значений:

>>> list(x)
[0, 1, 2, 3, 4]

>>> tuple(x)
(0, 1, 2, 3, 4)

Однако, когда range() используется в коде, который является частью более крупного приложения, обычно считается плохой практикой использовать list() или tuple() таким образом. Как и итераторы, range объекты ленивы – значения в указанном диапазоне не генерируются, пока их не запросят. Использование list() или объекта tuple() приводит к тому, что range все значения возвращаются одновременно. Это редко необходимо, и если список длинный, он может тратить время и память.

range(<begin>, <end>, <stride>) возвращает итерацию, которая дает целые числа, начиная с <begin>, до, но не включая <end>. Если указано, <stride> указывает количество пропускаемых значений (аналогично значению шага, используемому для нарезки строк и списков):

>>> list(range(5, 20, 3))
[5, 8, 11, 14, 17]

Если <stride> опущено, то по умолчанию 1:

>>> list(range(5, 10, 1))
[5, 6, 7, 8, 9]
>>> list(range(5, 10))
[5, 6, 7, 8, 9]

Все указанные параметры range() должны быть целыми числами, но любой из них может быть отрицательным. Естественно, если <begin> больше чем <end>, то <stride> должно быть отрицательным (если вы хотите каких-либо результатов):

>>> list(range(-5, 5))
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]

>>> list(range(5, -5))
[]
>>> list(range(5, -5, -1))
[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]

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

Изменение поведения цикла for

Вы видели в предыдущем блоке, как выполнение в while цикле может быть прервано с помощью break и continue, и также измененным с else . Эти возможности также доступны в for цикле.

break и continue

break и continue работает с for циклами так же, как с while циклами. break завершает цикл полностью и переходит к первому оператору, следующему за циклом:

>>> for i in ['foo', 'bar', 'baz', 'qux']:
...     if 'b' in i:
...         break
...     print(i)
...
foo

continue завершает текущую итерацию и переходит к следующей итерации:

>>> for i in ['foo', 'bar', 'baz', 'qux']:
...     if 'b' in i:
...         continue
...     print(i)
...
foo
qux

else

Цикл for может иметь else. Интерпретация аналогична интерпретации while цикла. else будет выполнено, если цикл завершится из-за исчерпания итерируемого:

>>> for i in ['foo', 'bar', 'baz', 'qux']:
...     print(i)
... else:
...     print('Done.')  # Will execute
...
foo
bar
baz
qux
Done.

else не будет выполнено, если список будет разбит breakоператором:

>>> for i in ['foo', 'bar', 'baz', 'qux']:
...     if i == 'bar':
...         break
...     print(i)
... else:
...     print('Done.')  # Will not execute
...
foo

Вывод

Вы узнали о внутренней работе итерируемых и итераторов , два важных типов объектов, лежащих в основе определенной итерации, но и занимает видное место в широком спектре другого кода Python.


Совершенствуй знания каждый день у нас в Телеграм-каналах

Вопросы, реклама — VK | Telegram