Cosa fa for row_number, row in enumerate(cursor):
in Python?
Cosa enumerate
significa in questo contesto?
Cosa fa for row_number, row in enumerate(cursor):
in Python?
Cosa enumerate
significa in questo contesto?
Risposte:
La enumerate()
funzione aggiunge un contatore a un iterabile.
Quindi per ogni elemento in cursor
, viene prodotta una tupla con (counter, element)
; il for
loop lo lega rispettivamente a row_number
e row
.
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
Per impostazione predefinita, enumerate()
inizia a contare 0
ma se gli dai un secondo argomento intero, inizierà invece da quel numero:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
Se dovessi implementare nuovamente enumerate()
in Python, ecco due modi per raggiungerlo; uno usa itertools.count()
per fare il conteggio, l'altro conta manualmente in una funzione di generatore :
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)
e
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
L' implementazione effettiva in C è più vicina a quest'ultima, con ottimizzazioni per riutilizzare un singolo oggetto tupla per il for i, ...
caso di disimballaggio comune e usando un valore intero C standard per il contatore fino a quando il contatore diventa troppo grande per evitare l'uso di un oggetto intero Python (che è senza limiti).
È una funzione incorporata che restituisce un oggetto che può essere ripetuto. Vedere la documentazione .
In breve, scorre sopra gli elementi di un iterabile (come un elenco), nonché un numero indice, combinati in una tupla:
for item in enumerate(["a", "b", "c"]):
print item
stampe
(0, "a")
(1, "b")
(2, "c")
È utile se si desidera eseguire il ciclo su una sequenza (o altra cosa iterabile) e si desidera anche disporre di un contatore dell'indice. Se vuoi che il contatore inizi da un altro valore (di solito 1), puoi fornirlo come secondo argomento enumerate
.
item
, puoi rimuovere la parentesi: D
yield
/ yield from
, o espressioni del generatore, che implicitamente yield
); enumerate
non è un generatore. Per tutti gli scopi legati alla tipizzazione delle anatre non vi è alcuna differenza, ma il controllo esplicito dei tipi e i documenti del linguaggio Python usano il termine "generatore" per un solo scopo, che non copre enumerate
.
Sto leggendo un libro ( Effective Python ) di Brett Slatkin e mostra un altro modo per scorrere su un elenco e anche conoscere l'indice dell'elemento corrente nell'elenco, ma mi suggerisce che è meglio non usarlo e usarlo enumerate
invece. So che hai chiesto cosa significhi enumerare, ma quando ho capito quanto segue, ho anche capito come enumerate
rendere iterare un elenco mentre conosco l'indice dell'elemento corrente più facile (e più leggibile).
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
L'output è:
0 a
1 b
2 c
Facevo anche qualcosa, ancor più sciocco prima di leggere la enumerate
funzione.
i = 0
for n in list_of_letters:
print (i, n)
i += 1
Produce lo stesso output.
Ma con enumerate
devo solo scrivere:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Come altri utenti hanno già detto, enumerate
è un generatore che aggiunge un indice incrementale accanto a ciascun elemento di un iterabile.
Quindi, se avete un dire l'elenco l = ["test_1", "test_2", "test_3"]
, il list(enumerate(l))
vi darà qualcosa di simile a questo: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
.
Ora, quando è utile? Un possibile caso d'uso è quando si desidera scorrere gli elementi e si desidera saltare un elemento specifico che si conosce solo il suo indice nell'elenco ma non il suo valore (perché il suo valore non è noto al momento).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
Quindi il tuo codice si legge meglio perché potresti anche fare un ciclo regolare con range
ma poi per accedere agli elementi che devi indicizzare (cioè, joint_values[i]
).
Sebbene un altro utente abbia menzionato un'implementazione enumerate
dell'utilizzo zip
, penso che un modo più puro (ma leggermente più complesso) senza usare itertools
sia il seguente:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Esempio:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Produzione:
[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]
Come menzionato nei commenti, questo approccio con range non funzionerà con iterabili arbitrari come fa la enumerate
funzione originale .
itertools
è che il tuo range
approccio funziona solo con i contenitori. enumerate
funziona con iterabili arbitrari; se vuoi iterare un file, for lineno, line in enumerate(myfile):
funziona, ma non puoi farlo range(len(myfile))
perché la lunghezza non è nota fino a quando non raggiungi EOF.
La funzione di enumerazione funziona come segue:
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)
L'output è
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')