Встроенная функция enumerate() позволяет, как следует из ее названия, перечислять коллекцию (например, список, кортеж или любой другой итерируемый объект).
Он работает, принимая в качестве аргумента любой итерируемый объект и возвращая новый, элементы которого являются кортежами из двух элементов: первый – индекс (начиная с нуля); второй – элемент на этой позиции в исходном итерируемом объекте.
languages = ["Java", "C", "C++", "Rust", "Elixir"]
arr = list(enumerate(languages))
print(arr)
Code language: PHP (php)
[(0, 'Java'), (1, 'C'), (2, 'C++'), (3, 'Rust'), (4, 'Elixir')]
Code language: JSON / JSON with Comments (json)
Чтобы сделать эту операцию максимально эффективной, элементы enumerate() (т.е. кортежи) генерируются по мере их использования.
Поэтому, если мы хотим увидеть полный результат, мы должны преобразовать его в список.
В большинстве случаев это не понадобится, так как мы будем использовать эту функцию в цикле.
Например, если мы хотим вывести на экран каждый из языков с соответствующей позицией в списке:
for i, languages in enumerate(languages):
print(i, languages)
Code language: PHP (php)
0 Java 1 C 2 C++ 3 Rust 4 Elixir
Или если мы хотим напечатать каждый из языков, но пропустить тот, который находится в позиции 2:
for i, languages in enumerate(languages):
if i != 2:
print(languages)
Code language: PHP (php)
Java C Rust Elixir
Мы можем заставить функцию начать перечисление с одного или любого другого числа, передав его в качестве второго аргумента:
for i, languages in enumerate(languages, 1):
print(i, languages)
Code language: PHP (php)
1 Java 2 C 3 C++ 4 Rust 5 Elixir
Мы говорили, что его можно применять и к другим итерируемым объектам.
Например, строке:
letters = "абвгдеежзийклмн"
for i, letter in enumerate(letters, 1):
print(i, letter)
Code language: PHP (php)
1 а 2 б 3 в 4 г 5 д 6 е 7 е 8 ж 9 з 10 и 11 й 12 к 13 л 14 м 15 н
Если этот синтаксис использования i, language или i, letter в цикле for кажется вам немного странным, давайте посмотрим подробнее, как это работает.
Давайте вспомним функцию unpacking.
Рассмотрим следующий кортеж:
t = (1, 2, 3)
Если мы хотим записать значения 1, 2 и 3 в три разные переменные, мы должны сделать следующее:
a = t[0] b = t[1] c = t[2]
Однако, используя функцию распаковки, мы получаем более компактный метод:
t = (1, 2, 3)
(a, b, c) = t
print(a)
print(b)
print(c)
Code language: PHP (php)
1 2 3
Круглые скобки можно опустить, поэтому в следующем примере также делается то же самое:
a, b, c = t
Давайте вернемся к примеру, который мы хотели разобрать:
for i, languages in enumerate(languages):
print(i, languages)
Code language: PHP (php)
Пойдем шаг за шагом.
Мы знаем, что каждый из элементов, полученных с помощью enumerate(), является кортежем, поэтому следующий код выводит каждый из этих кортежей.
for t in enumerate(languages):
print(t)
Code language: PHP (php)
(0, 'Java')
(1, 'C')
(2, 'C++')
(3, 'Rust')
(4, 'Elixir')
Code language: JavaScript (javascript)
Первым элементом каждого из этих кортежей был индекс или позиция, а вторым – элемент языка.
Мы можем поместить их в две разные переменные:
for t in enumerate(languages):
index = t[0]
language = t[1]
print(index, language)
Code language: PHP (php)
0 Java 1 C 2 C++ 3 Rust 4 Elixir
Используя unpacking, это можно упросить следующим образом:
for t in enumerate(languages):
index, language = t
print(index, language)
Code language: PHP (php)
0 Java 1 C 2 C++ 3 Rust 4 Elixir
Более того: поскольку t используется только для присвоения значений index и language, Python позволяет нам разместить этот шаблон (т.е. index, language) непосредственно одной строкой выше, без необходимости создавать промежуточную переменную (t).
for index, language in enumerate(languages):
print(index, language)
Code language: PHP (php)
Сокращая index как i, мы получаем следующий код:
for i, language in enumerate(languages):
print(i, language)
Code language: PHP (php)
0 Java 1 C 2 C++ 3 Rust 4 Elixir
Некоторые программисты, привыкшие к другим языкам, часто делают так, вместо того чтобы использовать enumerate():
for i in range(len(languages)):
print(i, languages[i])
Code language: CSS (css)
0 Java 1 C 2 C++ 3 Rust 4 Elixir
Такой метод менее эффективен (он включает вызов дополнительной функции) и менее читабелен.