Что означает enumerate()?

Что делает for row_number, row in enumerate(cursor): делать в Python?

Что означает enumerate в этом контексте?

Ответ 1

Функция enumerate() добавляет счетчик к итерируемому.

Таким образом, для каждого элемента в cursor создается кортеж с помощью (counter, element); цикл for связывает это с row_number и row, соответственно.

Демо-версия:

>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
...     print elem
... 
foo
bar
baz
>>> for count, elem in enumerate(elements):
...     print count, elem
... 
0 foo
1 bar
2 baz

По умолчанию enumerate() начинает считать с 0 но если вы дадите ему второй целочисленный аргумент, он будет начинаться с этого числа:

>>> for count, elem in enumerate(elements, 42):
...     print count, elem
... 
42 foo
43 bar
44 baz

Если бы вам пришлось заново реализовать enumerate() в Python, вот два способа добиться этого; один использует itertools.count() для подсчета, другой - вручную в функции генератора:

from itertools import count

def enumerate(it, start=0):
    # return an iterator that adds a counter to each element of it
    return zip(count(start), it)

а также

def enumerate(it, start=0):
    count = start
    for elem in it:
        yield (count, elem)
        count += 1

Реальная реализация в C ближе к последнему, с оптимизацией для повторного использования одного объекта кортежа для общего случая распаковки for i,... и использования стандартного целочисленного значения C для счетчика, пока счетчик не станет слишком большим, чтобы избежать использования Целочисленный объект Python (который не ограничен).

Ответ 2

Это встроенная функция, которая возвращает объект, который можно повторять, см. http://docs.python.org/2/library/functions.html#enumerate.

Короче говоря, он проходит по элементам итерируемого (например, списка), а также по порядковому номеру, объединенному в кортеж:

for item in enumerate(["a", "b", "c"]):
    print item

печатает

(0, "a")
(1, "b")
(2, "c")

Это полезно, если вы хотите перебрать последовательность (или другую итеративную вещь), а также хотите, чтобы был доступен счетчик индекса. Если вы хотите, чтобы счетчик начинался с какого-то другого значения (обычно 1), вы можете указать его в качестве второго аргумента для enumerate.

Ответ 3

Я читаю книгу ("Эффективный Питон") Бретта Слаткина, и он показывает другой способ перебора списка, а также знает индекс текущего элемента в списке. НО предлагает не использовать его и использовать enumerate вместо этого. Я знаю, что вы спросили, что означает перечисление, но когда я понял следующее, я также понял, как enumerate делает итерацию по списку, одновременно зная индекс текущего элемента (и более читаемый).

list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
    letter = list_of_letters[i]
    print (i, letter)

Выход:

0 a
1 b
2 c

Я также делал что-то, еще глупее, прежде чем читать о функции enumerate.

i = 0
for n in list_of_letters:
    print (i, n)
    i = i +1

Он производит тот же результат.

Но с enumerate мне просто нужно написать:

list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
    print (i, letter)

Ответ 4

Как уже упоминали другие пользователи, enumerate - это генератор, который добавляет инкрементный индекс рядом с каждым элементом итерируемого.

Так что если у вас есть список, скажем, l = ["test_1", "test_2", "test_3"], list(enumerate(l)) даст вам что-то вроде этого: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')].

Теперь, когда это полезно? Возможный вариант использования - это когда вы хотите перебирать элементы и хотите пропустить конкретный элемент, для которого вы знаете только его индекс в списке, но не его значение (потому что его значение в данный момент неизвестно).

for index, value in enumerate(joint_values):
   if index == 3:
       continue

   # Do something with the other 'value'

Таким образом, ваш код читается лучше, потому что вы также можете сделать обычный цикл for с range но затем для доступа к элементам вам нужно их проиндексировать (т. joint_values[i]).

Хотя другой пользователь упомянул реализацию enumerate с использованием zip, я думаю, что более чистый (но немного более сложный) способ без использования itertools заключается в следующем:

def enumerate(l, start=0):
    return zip(range(start, len(l) + start), l)

Пример:

l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)

Выход:

[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]

[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]

Как упоминалось в комментариях, этот подход с диапазоном не будет работать с произвольными итерациями, как это делает оригинальная функция enumerate.

Ответ 5

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

doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
     print(i)

Выход

(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')