J'ai le code suivant qui fait partie d'un tutoriel
import csv as csv
import numpy as np
csv_file_object = csv.reader(open("train.csv", 'rb'))
header = csv_file_object.next()
data = []
for row in csv_file_object:
data.append(row)
data = np.array(data)
le code fonctionne comme il est supposé, mais je ne comprends pas vraiment pourquoi l'appel de .next()
sur le fichier avec la variable header
fonctionne. Csv_file_object n'est-il pas encore le fichier entier? Comment le programme sait-il ignorer la ligne d'en-tête lorsque for row in csv_file_object
est appelé puisqu'il ne semble pas que l'en-tête de variable soit référencé une fois défini?
La ligne d'en-tête est "ignorée" à la suite de l'appel de next()
. C'est comme ça que fonctionnent les itérateurs.
Lorsque vous passez en boucle sur un itérateur, sa méthode next()
est appelée à chaque fois. Chaque appel avance l'itérateur. Lorsque la boucle for
commence, l'itérateur est déjà à la deuxième ligne et continue à partir de là.
Voici la documentation sur la méthode next()
( voici un autre morceau ).
Ce qui est important, c'est que les objets csv.reader
sont des itérateurs, tout comme les objets fichier renvoyés par open()
. Vous pouvez les parcourir, mais elles ne contiennent pas toutes les lignes (ni aucune des lignes) à un moment donné.
L'objet csv.reader
est un itérateur. Un itérateur est un objet avec une méthode next()
qui renverra la prochaine valeur disponible ou levera StopIteration
si aucune valeur n'est disponible. Le csv.reader
renvoie la valeur ligne par ligne.
Les objets itérateurs décrivent comment python implémente la boucle for
. Au début de la boucle, l'objet __iter__
de l'objet bouclé sera appelé. Il doit retourner un itérateur. Ensuite, la méthode next
de cet objet sera appelée et la valeur stockée dans la variable de boucle jusqu'à ce que la méthode next
lève une exception StopIteration
.
Dans votre exemple, en ajoutant un appel à next avant d'utiliser la variable dans la construction de boucle for
, vous supprimez la première valeur du flux de valeurs renvoyé par l'itérateur.
Vous pouvez voir le même effet avec des itérateurs plus simples:
iterator = [0, 1, 2, 3, 4, 5].__iter__()
value = iterator.next()
for v in iterator:
print v,
1 2 3 4 5
print value
0
Csv.reader est un itérateur. Si vous appelez .next (), vous obtiendrez la valeur suivante lors de son itération dans le fichier.
Dans le code ci-dessous, la boucle for appelle .next () sur l'itérateur à chaque fois et alloue le résultat de à côté de la ligne de variable.
for row in csv_file_object:
data.append(row)
csv.reader est un itérateur. Il lit une ligne du csv chaque fois que .next est appelé. Voici la documentation: http://docs.python.org/2/library/csv.html . Un objet itérateur peut en réalité renvoyer des valeurs provenant d'une source trop volumineuse pour être lue en une fois. utiliser une boucle for avec un itérateur appelle effectivement .next à chaque fois à travers la boucle.
Le comportement de next () est plus que cela, tout exposer ci-dessus est ok mais il y a une chose qui manque, utilisez aussi next pour indiquer à l'itérateur à partir de quelle ligne vous voulez commencer l'itération, donc c'est un problème, disons que j'en veux valeur qui est dans la ligne 3 sans passer par toutes les lignes que je peux facilement utiliser ensuite, j'ai la valeur, mais si j'ai besoin d'itérer sur la première ligne dans mon cas, je ne peux pas car peu importe ce que l'itérateur commence toujours à la ligne 3 donc je ne peux pas partir de la ligne 1 et bien il y a un moyen mais je ne l'ai pas encore trouvé.