На этом шаге мы рассмотрим назначение и примеры использования этих функций.
До сих пор мы только выводили элементы последовательностей. Теперь попробуем умножить каждый элемент списка на 2:
arr = [1, 2, 3] for i in arr: i = i * 2 print(arr)
Рис.1. Текст программы и результат выполнения
Как видно из примера, список не изменился. Переменная i на каждой итерации цикла содержит лишь копию значения текущего элемента списка. Изменить таким способом элементы списка нельзя. Чтобы получить доступ к каждому элементу, можно, например, воспользоваться функцией range () для генерации индексов. Функция range() имеет следующий формат:
range([<Начало>, ]<Конец>[, <Шаг>])
Первый параметр задает начальное значение. Если параметр <Начало> не указан, то по умолчанию используется значение 0. Во втором параметре указывается конечное значение. Следует заметить, что это значение не входит в возвращаемые значения. Если параметр <Шаг> не указан, то используется значение 1. Функция возвращает диапазон - особый объект, поддерживающий итерационный протокол. С помощью диапазона внутри цикла for можно получить значение текущего элемента. В качестве примера умножим каждый элемент списка на 2 (рисунок 2).
arr = [1, 2, 3] for i in range(len(arr)): arr[i] *= 2 print(arr)
Рис.2. Текст программы и результат выполнения
В этом примере мы получаем количество элементов списка с помощью функции len () и передаем результат в функцию range (). В итоге функция range() возвращает диапазон значений от 0 до len (arr) - 1. На каждой итерации цикла через переменную i доступен текущий элемент из диапазона индексов. Чтобы получить доступ к элементу списка, указываем индекс внутри квадратных скобок. Умножаем каждый элемент списка на 2, а затем выводим результат с помощью функции print ().
Рассмотрим несколько примеров использования функции range(). Выведем числа от 1 до 100:
for i in range(1, 101): print(i)
Можно не только увеличивать значение, но и уменьшать его. Выведем все числа от 100 до 1:
for i in range(100, 0, -1): print(i)
Можно также изменять значение не только на единицу. Выведем все четные числа от 1 до 100:
for i in range(2, 101, 2): print(i)
В Python 3 поведение функция range() возвращает диапазон. Чтобы получить список чисел, следует передать диапазон, возвращенный функцией range(), в функцию list() (рисунок 3).
>>> obj = range(len([1, 2, 3])) >>> obj range(0, 3) >>> obj[0], obj[1], obj[2] # Доступ по индексу (0, 1, 2) >>> obj[0:2] # Получение среза range(0, 2) >>> i = iter(obj) >>> next(i), next(i), next(i) # Доступ с помощью итераторов (0, 1, 2) >>> list(obj) # Преобразование диапазона в список [0, 1, 2] >>> 1 in obj, 7 in obj # Проверка вхождения значения (True, False)
Рис.3. Создание списка чисел на основе диапазона
Диапазон поддерживает два полезных метода:
>>> obj = range(1, 5) >>> obj.index(1), obj.index(4) (0, 3) >>> obj.index(5) Traceback (most recent call last): File "<pyshell#11>", line 1, in <module> obj.index(5) ValueError: 5 is not in range
>>> obj = range(1, 5) >>> obj.count(1), obj.count(10) (1, 0)
Функция enumerate (<объект>[, start=0]) на каждой итерации цикла for возвращает кортеж из индекса и значения текущего элемента. С помощью необязательного параметра start можно задать начальное значение индекса. В качестве примера умножим на 2 каждый элемент списка, который содержит четное число (рисунок 4).
arr = [1, 2, 3, 4, 5, 6] for i, elem in enumerate(arr): if elem % 2 == 0: arr[i] *= 2 print(arr)
Рис.4. Пример использования функции enumerate(). Текст программы и результат выполнения
Функция enumerate() не создает список, а возвращает итератор. С помощью функции next() можно обойти всю последовательность. Когда перебор будет закончен, возбуждается исключение StopIteration:
>>> arr = [1, 2] >>> obj = enumerate(arr, start=2) >>> next(obj) (2, 1) >>> next(obj) (3, 2) >>> next(obj) Traceback (most recent call last): File "<pyshell#20>", line 1, in <module> next(obj) StopIteration
Кстати, цикл for при работе активно использует итераторы, но делает это незаметно для нас.
На следующем шаге мы рассмотрим цикл while.