Що for row_number, row in enumerate(cursor):
робити в Python?
Що enumerate
означає в цьому контексті?
Що for row_number, row in enumerate(cursor):
робити в Python?
Що enumerate
означає в цьому контексті?
Відповіді:
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, ...
розпакування справи і з використанням стандартного З цілочисельного значення для лічильника , поки лічильник не стає занадто великим , щоб уникнути використання целочисленного об'єкта Python (який є необмежений).
Це вбудована функція, яка повертає об'єкт, який можна повторити. Дивіться документацію .
Коротше кажучи, вона перетинає елементи перегляду (як список), а також номер індексу, об'єднаний у кортеж:
for item in enumerate(["a", "b", "c"]):
print item
відбитки
(0, "a")
(1, "b")
(2, "c")
Це корисно, якщо ви хочете перевести цикл на послідовність (або іншу річ), а також хочете мати лічильник індексів. Якщо ви хочете, щоб лічильник починався з якогось іншого значення (зазвичай 1), ви можете надати це як другий аргумент enumerate
.
item
ви можете видалити круглі дужки: D
yield
/ yield from
або вирази генератора, що неявно yield
); enumerate
не генератор. Для всіх цілей, пов’язаних із набором качок, немає різниці, але явна перевірка типу та документи мови Python використовують лише термін "генератор" для однієї мети, який не охоплює enumerate
.
Я читаю книгу ( Ефективний Python ) Бретта Слаткіна, і він показує інший спосіб перебору списку, а також знаю індекс поточного елемента в списку, але він припускає, що краще не використовувати його, а використовувати 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 += 1
Це дає такий же вихід.
Але з цим enumerate
я просто повинен написати:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Як згадували інші користувачі, 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`
Таким чином, ваш код читається краще, тому що ви також можете зробити звичайний цикл за допомогою, 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
робить оригінальна функція.
itertools
полягає в тому, що ваш range
підхід працює лише з контейнерами. enumerate
працює з довільними ітерабелями; якщо ви хочете повторити файл, for lineno, line in enumerate(myfile):
працює, але ви не можете цього зробити, range(len(myfile))
оскільки довжина не відома, поки ви не досягнете EOF.
Функція перерахування працює наступним чином:
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')