Was macht for row_number, row in enumerate(cursor):
man in Python?
Was enumerate
bedeutet in diesem Zusammenhang?
Was macht for row_number, row in enumerate(cursor):
man in Python?
Was enumerate
bedeutet in diesem Zusammenhang?
Antworten:
Die enumerate()
Funktion fügt einem Iterable einen Zähler hinzu.
Für jedes Element in cursor
wird also ein Tupel mit erzeugt (counter, element)
; die for
Schleife bindet , die zu row_number
und row
verbunden.
Demo:
>>> 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
Standardmäßig enumerate()
beginnt die Zählung bei, 0
aber wenn Sie ein zweites ganzzahliges Argument angeben, beginnt es stattdessen mit dieser Zahl:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
Wenn Sie enumerate()
in Python erneut implementieren , gibt es zwei Möglichkeiten, dies zu erreichen. einer verwendet itertools.count()
zum Zählen, der andere manuell in einer Generatorfunktion :
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)
und
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
Die tatsächliche Implementierung in C ist näher an letzterer, mit Optimierungen zur Wiederverwendung eines einzelnen Tupelobjekts für den allgemeinen for i, ...
Entpackungsfall und Verwendung eines Standard-C-Integer-Werts für den Zähler, bis der Zähler zu groß wird, um die Verwendung eines Python-Integer-Objekts (dh) zu vermeiden unbegrenzt).
Es ist eine integrierte Funktion, die ein Objekt zurückgibt, über das iteriert werden kann. Siehe die Dokumentation .
Kurz gesagt, es werden die Elemente einer iterierbaren Datei (wie eine Liste) sowie eine Indexnummer, die in einem Tupel zusammengefasst sind, durchlaufen:
for item in enumerate(["a", "b", "c"]):
print item
druckt
(0, "a")
(1, "b")
(2, "c")
Dies ist hilfreich, wenn Sie eine Sequenz (oder eine andere iterierbare Sache) durchlaufen und einen Indexzähler zur Verfügung haben möchten. Wenn Sie möchten, dass der Zähler von einem anderen Wert (normalerweise 1) ausgeht, können Sie dies als zweites Argument angeben enumerate
.
item
, können Sie die Klammer entfernen: D
yield
/ yield from
oder Generatorausdrücken, die implizit verwendet werden yield
). enumerate
ist kein Generator. Für alle Zwecke im Zusammenhang mit der Ententypisierung gibt es keinen Unterschied, aber die explizite Typprüfung und die Python-Sprachdokumente verwenden nur den Begriff "Generator" für einen Zweck, der nicht behandelt wird enumerate
.
Ich lese ein Buch ( Effective Python ) von Brett Slatkin und er zeigt eine andere Möglichkeit, eine Liste zu durchlaufen und auch den Index des aktuellen Elements in der Liste zu kennen, aber er schlägt vor, dass es besser ist, es nicht zu verwenden und enumerate
stattdessen zu verwenden . Ich weiß, dass Sie gefragt haben, was Aufzählung bedeutet, aber als ich Folgendes verstanden habe, habe ich auch verstanden, wie enumerate
das Durchlaufen einer Liste erleichtert wird, während der Index des aktuellen Elements einfacher (und besser lesbar) ist.
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
Die Ausgabe ist:
0 a
1 b
2 c
Ich habe auch etwas getan, noch dümmer, bevor ich über die enumerate
Funktion gelesen habe .
i = 0
for n in list_of_letters:
print (i, n)
i += 1
Es erzeugt die gleiche Ausgabe.
Aber mit muss enumerate
ich nur schreiben:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Wie andere Benutzer bereits erwähnt haben, enumerate
handelt es sich um einen Generator, der neben jedem Element eines iterablen Elements einen inkrementellen Index hinzufügt.
Wenn Sie also eine Liste zu sagen haben l = ["test_1", "test_2", "test_3"]
, das list(enumerate(l))
wird Ihnen etwas wie folgt aus : [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
.
Wann ist das sinnvoll? Ein möglicher Anwendungsfall ist, wenn Sie Elemente durchlaufen möchten und ein bestimmtes Element überspringen möchten, dessen Index in der Liste nur bekannt ist, dessen Wert jedoch nicht (da sein Wert zu diesem Zeitpunkt nicht bekannt ist).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
Ihr Code liest sich also besser, da Sie auch eine reguläre for-Schleife mit ausführen können, range
aber dann auf die Elemente zugreifen können, die Sie indizieren müssen (dh joint_values[i]
).
Obwohl ein anderer Benutzer eine Implementierung der enumerate
Verwendung erwähnte zip
, denke ich, dass eine reinere (aber etwas komplexere) Methode ohne Verwendung itertools
die folgende ist:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Beispiel:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Ausgabe:
[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]
Wie in den Kommentaren erwähnt, enumerate
funktioniert dieser Ansatz mit Bereich nicht mit beliebigen Iterablen wie die ursprüngliche Funktion.
itertools
ist, dass Ihr range
Ansatz nur mit Containern funktioniert. enumerate
arbeitet mit beliebigen iterables; Wenn Sie eine Datei iterieren möchten, for lineno, line in enumerate(myfile):
funktioniert dies, dies ist jedoch nicht möglich, range(len(myfile))
da die Länge erst bekannt ist, wenn Sie EOF erreichen.
Die Aufzählungsfunktion funktioniert wie folgt:
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)
Die Ausgabe ist
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')