Оглавление
- Цикл 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
показано на следующей диаграмме:

Вот файл сценария с именем 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
становится 2
, break
заявление выполняется, цикл полностью завершается, и выполнение программы переходит к 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
равно 2
, continue
оператор вызывает завершение этой итерации. Таким образом, 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 итерируемых и итераторов предостаточно:
- Многие встроенные и библиотечные объекты являются итеративными.
- Существует модуль стандартной библиотеки под названием 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.