Que fait for row_number, row in enumerate(cursor):
-on en Python?
Que enumerate
signifie dans ce contexte?
Que fait for row_number, row in enumerate(cursor):
-on en Python?
Que enumerate
signifie dans ce contexte?
Réponses:
La enumerate()
fonction ajoute un compteur à un itérable.
Ainsi, pour chaque élément de cursor
, un tuple est produit avec (counter, element)
; la for
boucle lie cela à row_number
et row
, respectivement.
Démo:
>>> 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
Par défaut, enumerate()
commence à compter 0
mais si vous lui donnez un deuxième argument entier, il commencera à partir de ce nombre à la place:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
Si vous deviez réimplémenter enumerate()
en Python, voici deux façons d'y parvenir; l'un utilisant itertools.count()
pour effectuer le comptage, l'autre comptant manuellement dans une fonction générateur :
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)
et
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
L' implémentation réelle en C est plus proche de ce dernier, avec des optimisations pour réutiliser un seul objet tuple pour le for i, ...
cas de déballage commun et en utilisant une valeur entière C standard pour le compteur jusqu'à ce que le compteur devienne trop grand pour éviter d'utiliser un objet entier Python (qui est sans bornes).
C'est une fonction intégrée qui renvoie un objet qui peut être itéré. Consultez la documentation .
En bref, il boucle sur les éléments d'un itérable (comme une liste), ainsi que d'un numéro d'index, combinés dans un tuple:
for item in enumerate(["a", "b", "c"]):
print item
impressions
(0, "a")
(1, "b")
(2, "c")
C'est utile si vous voulez faire une boucle sur une séquence (ou autre chose itérable), et que vous voulez également avoir un compteur d'index disponible. Si vous voulez que le compteur démarre à partir d'une autre valeur (généralement 1), vous pouvez donner cela comme deuxième argument à enumerate
.
item
alors vous pouvez supprimer la parenthèse: D
yield
/ yield from
, ou des expressions de générateur, qui implicitement yield
); enumerate
n'est pas un générateur. Pour toutes les fins liées à la saisie de canard, il n'y a pas de différence, mais la vérification de type explicite et les documents en langage Python n'utilisent le terme "générateur" que pour un seul but, qui ne couvre pas enumerate
.
Je lis un livre ( Effective Python ) de Brett Slatkin et il montre une autre façon de parcourir une liste et de connaître également l'index de l'élément actuel dans la liste, mais il suggère qu'il vaut mieux ne pas l'utiliser et l'utiliser à la enumerate
place. Je sais que vous avez demandé ce que signifie énumérer, mais quand j'ai compris ce qui suit, j'ai également compris comment enumerate
faciliter l'itération sur une liste tout en connaissant l'index de l'élément actuel (et plus lisible).
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
La sortie est:
0 a
1 b
2 c
J'ai aussi l'habitude de faire quelque chose, encore plus idiot avant de lire sur la enumerate
fonction.
i = 0
for n in list_of_letters:
print (i, n)
i += 1
Il produit la même sortie.
Mais avec enumerate
je dois juste écrire:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Comme d'autres utilisateurs l'ont mentionné, enumerate
est un générateur qui ajoute un index incrémentiel à côté de chaque élément d'un itérable.
Donc , si vous avez un mot à dire la liste l = ["test_1", "test_2", "test_3"]
, la list(enumerate(l))
vous donnera quelque chose comme ceci: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
.
Maintenant, quand c'est utile? Un cas d'utilisation possible consiste à parcourir les éléments et à ignorer un élément spécifique dont vous ne connaissez que l'index dans la liste mais pas sa valeur (car sa valeur n'est pas connue à ce moment-là).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
Ainsi, votre code se lit mieux car vous pouvez également faire une boucle for régulière avec range
mais pour accéder aux éléments dont vous avez besoin pour les indexer (c'est-à-dire joint_values[i]
).
Bien qu'un autre utilisateur ait mentionné une implémentation de l' enumerate
utilisation zip
, je pense qu'une manière plus pure (mais légèrement plus complexe) sans utiliser itertools
est la suivante:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Exemple:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Production:
[(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
[(10, 'test_1'), (11, 'test_2'), (12, 'test_3')]
Comme mentionné dans les commentaires, cette approche avec plage ne fonctionnera pas avec des itérables arbitraires comme le enumerate
fait la fonction d' origine .
itertools
est que votre range
approche ne fonctionne qu'avec des conteneurs. enumerate
fonctionne avec des itérables arbitraires; si vous voulez itérer un fichier, for lineno, line in enumerate(myfile):
ça marche, mais vous ne pouvez pas le faire range(len(myfile))
car la longueur n'est pas connue jusqu'à ce que vous atteigniez EOF.
La fonction énumération fonctionne comme suit:
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)
La sortie est
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')