Was bedeutet enumerate ()?


Antworten:


513

Die enumerate()Funktion fügt einem Iterable einen Zähler hinzu.

Für jedes Element in cursorwird also ein Tupel mit erzeugt (counter, element); die forSchleife bindet , die zu row_numberund rowverbunden.

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, 0aber 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).


92

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.


1
Wenn Sie eine zweite Variable hinzufügen item, können Sie die Klammer entfernen: D
Abdelouahab

2
Pedantisch: Es ist eine Funktion, die einen Iterator zurückgibt, keinen Generator. Generatoren sind eine bestimmte Klasse von benutzerdefinierten Funktionen (unter Verwendung von yield/ yield fromoder Generatorausdrücken, die implizit verwendet werden yield). enumerateist 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.
ShadowRanger

22

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 enumeratestattdessen zu verwenden . Ich weiß, dass Sie gefragt haben, was Aufzählung bedeutet, aber als ich Folgendes verstanden habe, habe ich auch verstanden, wie enumeratedas 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 enumerateFunktion gelesen habe .

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

Es erzeugt die gleiche Ausgabe.

Aber mit muss enumerateich nur schreiben:

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

20

Wie andere Benutzer bereits erwähnt haben, enumeratehandelt 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, rangeaber dann auf die Elemente zugreifen können, die Sie indizieren müssen (dh joint_values[i]).

Obwohl ein anderer Benutzer eine Implementierung der enumerateVerwendung erwähnte zip, denke ich, dass eine reinere (aber etwas komplexere) Methode ohne Verwendung itertoolsdie 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, enumeratefunktioniert dieser Ansatz mit Bereich nicht mit beliebigen Iterablen wie die ursprüngliche Funktion.


Der Grund, warum die andere Antwort erwähnt, itertoolsist, dass Ihr rangeAnsatz nur mit Containern funktioniert. enumeratearbeitet 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.
ShadowRanger

12

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')
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.