for/in
в Python;for/in
в Python;else
в циклах for/in
.for/in
в Python.При итерации по элементам словаря for/in
, ключ и соответствующее значение могут быть получены одновременно с использованием метода словаря dict.items()
:
>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'} >>> for k, v in knights.items(): ... print(k, v) ... # gallahad the pure # robin the brave
Смотрите материал "Сортировка словаря по значению и ключу в Python", чтобы перебрать его в отсортированном виде по ключам или значениям.
for/in
в Python.При итерации по последовательности с помощью инструкции for/in
индекс позиции и соответствующее значение могут быть получены одновременно с помощью встроенной функции enumerate()
.
>>> for i, v in enumerate(['tic', 'tac', 'toe']): ... print(i, v) ... # 0 tic # 1 tac # 2 toe
Чтобы выполнить цикл над двумя или более последовательностями одновременно, списки могут быть соединены с помощью встроенной функции zip()
.
>>> questions = ['name', 'quest', 'favorite color'] >>> answers = ['lancelot', 'the holy grail', 'blue'] >>> for q, a in zip(questions, answers): ... print('What is your {0}? It is {1}.'.format(q, a)) ... # What is your name? It is lancelot. # What is your quest? It is the holy grail. # What is your favorite color? It is blue.
Еще пример:
>>> lst1 = [0, 1, 2, 3, 4, 5] >>> lst2 = [5, 3, 2, 0, 4, 1] >>> lst3 = ['zero', 'one', 'two', 'three', 'four', 'five'] >>> for a, b, c in zip(lst1, lst2, lst3): ... print(f'{c}:\t{a} + {b} = {a + b}') ... # zero: 0 + 5 = 5 # one: 1 + 3 = 4 # two: 2 + 2 = 4 # three: 3 + 0 = 3 # four: 4 + 4 = 8 # five: 5 + 1 = 6
Чтобы выполнить цикл над последовательностью в обратном направлении используйте встроенную функцию reversed()
.
>>> for i in reversed(range(1, 10, 2)): ... print(i) ... # 9 # 7 # 5 # 3 # 1
Для циклического перебора последовательности в отсортированном порядке используйте встроенную функцию sorted()
, которая возвращает новый отсортированный список, оставляя исходную последовательность неизменной.
>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] >>> for f in sorted(basket): ... print(f) ... # apple # banana # orange # pear
Иногда возникает соблазн изменить список во время выполнения цикла. Не делайте этого, так как это может привести к непредсказуемым результатам. Зачастую проще и безопаснее создать список с новыми значениями, или по крайней мере изменяйте копию list.copy()
исходного списка.
Пример, с созданием списка для новых значений.
>>> import math # не изменяйте исходный список во время итерации >>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8] # создаем список для отобранных значений >>> filtered_data = [] >>> for value in raw_data: ... if not math.isnan(value): ... filtered_data.append(value) ... >>> filtered_data # [56.2, 51.7, 55.3, 52.5, 47.8]
else
в циклах for/in
.Оператор else
в циклах for/in
выполняется только если цикл закончился и не прервался оператором break
. Звучит как то бессмысленно. Как можно использовать такое поведение?
Цикл for/in/else
упрощает любой цикл, который использует логический флаг, подобный этому:
# флаг принятия дальнейшего решения found = False for divisor in range(2, n): if n % divisor == 0: # если найден делитель, то меняем # флаг на `True` и выходим из цикла found = True break # принимаем решение на основе значения флага if found: print(n, 'is composite') else: print(n, 'is prime')
Оператор else
в for/in
позволяет опустить флаг и сделать код выше компактнее:
for divisor in range(2, n): if n % divisor == 0: print(n, 'is composite') break else: # else сработает, если цикл не завершиться # по `break`, т.е. преждевременно print(n, 'is prime')
Обратите внимание, что для кода, в котором принимается решение, что делать, уже есть естественное место для его выполнения (перед оператором break
). Единственная новая функция здесь - это место для выполнения кода, когда не нашлось ни одного делителя divisor
.
Такое поведение for/in/else
работает только в сочетании с оператором break
. Но все равно нужны логические значения (флаги), если например, ищется последнее совпадение или необходимо отслеживать несколько условий параллельно.
Если единственной целью цикла for/in
является ответ да или нет (флаг принятия решения), то можно написать его намного короче с помощью встроенных функций any()
/all()
и выражение-генератор, которое дает логические значения:
if any(n % divisor == 0 for divisor in range(2, n)): print(n, 'is composite') else: print(n, "is prime")
Этот код эффективен, как цикл с прерыванием, т.к. в функции any()
происходит замыкание, а выражение-генератор выполняется только до тех пор, пока оно не вернет значение True
. Этот код даже быстрее, чем цикл.