2010-07-20 10 views
2

Je dois lire deux fichiers CSV, combiner la ligne et écrire le résultat dans un troisième fichier CSV. premier fichier de format CSV possède cinq rangées avec un nom d'utilisateur dans le premier colunm. (25 colunm au total) deuxième fichier de format CSV avoir cinq rangs avec le nom d'utilisateur dans le premier colunm et l'ID d'utilisateur en second colunm. (Seulement 2 colunm)Problème avec les boucles imbriquées

le troisième fichier csv contiendra le nom d'utilisateur + userid et toutes les 24 colonnes restantes du premier fichier.

data = open(os.path.join("c:\\transales","AccountID+ContactID-source1.csv"),"rb").read().replace(";",",").replace("\0","") 
data2 = open(os.path.join("c:\\transales","AccountID+ContactID-source2.csv"),"rb").read().replace(";",",").replace("\0","") 

i = 0 
j = 0 
Info_Client_source1=StringIO.StringIO(data) 
Info_Client_source2=StringIO.StringIO(data2) 


for line in csv.reader(Info_Client_source1): 
    name= line[1] 
    i=i+1 
    print "i= ",i 
    for line2 in csv.reader(Info_Client_source2): 
     print "j = :",j 
     j=j+1 
     if line[1] == line2[2]: 
      continue 

le résultat:

i= 1 
j = : 0 
j = : 1 
j = : 2 
j = : 3 
j = : 4 
j = : 5 
j = : 6 
i= 2 
i= 3 
i= 4 
i= 5 
i= 6 
i= 7 

pourquoi, après i = 2 la seconf boucle ne rien faire ?? Je pense avoir i = 2, j = 0 à 6, i = 3 j = 0 ro 6, ...

Répondre

1

Parce qu'une fois que le csv.reader atteint la fin du fichier, il n'exécutera plus . Pour un petit jeu de données comme celui-ci, vous pouvez facilement lire vos données dans une liste ou un dictionnaire et parcourir ces données.

0

Il pourrait être une solution facile ... essayez de déplacer votre déclaration pour Info_Client_source2 dans la première boucle:

Info_Client_source1=StringIO.StringIO(data) 


for line in csv.reader(Info_Client_source1): 
    Info_Client_source2=StringIO.StringIO(data2) 
    name= line[1] 
    i=i+1 
    print "i= ",i 
    for line2 in csv.reader(Info_Client_source2): 
     print "j = :",j 
     j=j+1 
     if line[1] == line2[2]: 
      continue 
6

Il est parce que vous lire le contenu de votre objet StringIO dans le premier passage, en laissant la curseur à la fin de la chaîne. Au deuxième passage, il n'y a plus rien à lire, alors vous vous retrouvez avec un lecteur vide.

Aussi, ce n'est probablement pas une bonne idée d'appeler csv.reader() pour chaque itération interne de votre boucle. Permettez-moi de reformuler votre code puis expliquer mes changements:

data = open(os.path.join("c:\\transales","AccountID+ContactID-source1.csv"),"rb").read().replace(";",",").replace("\0","") 
data2 = open(os.path.join("c:\\transales","AccountID+ContactID-source2.csv"),"rb").read().replace(";",",").replace("\0","") 

source1 = csv.reader(data) 
source2 = csv.reader(data2) 

for line in source1: 
    name= line[1] 
    i=i+1 
    print "i= ",i 
    data2.seek(0) 
    for line2 in source2: 
     print "j = :",j 
     j=j+1 
     if line[1] == line2[2]: 
      continue 

Changements:

  • J'ai enlevé l'étape étrangère de créer un objet StringIO; vous pouvez simplement passer un handle de fichier standard à csv.reader() et cela fonctionnera bien. (S'il y a une raison pour créer ces objets StringIO, n'hésitez pas à rajouter ...)
  • J'ai déplacé l'initialisation des lecteurs en dehors de la boucle for. Bien qu'il soit normal que la source1 soit initialisée dans la boucle externe, le fait d'avoir initialisé la source2 dans la boucle interne est plutôt inefficace. Plus important encore, l'appel de data2.seek (0) réinitialise le curseur sur le descripteur de fichier sous-jacent, ce qui vous permet de lire plusieurs fois des données2.

Voici une question similaire sur le SO, ce qui pourrait mieux illustrer l'idée:

StackOverflow: Reading from CSVs in Python repeatedly?

Hope it helps.:)

1

Plus pythonic serait:

filename1 = os.path.join('c:\\transales', 'AccountID+ContactID-source1.csv') 
filename2 = os.path.join('c:\\transales', 'AccountID+ContactID-source2.csv') 

with open(filename1, 'rb') as file1, open(filename2, 'rb') as file2: 

    csv1 = csv.reader(file1, delimiter=';') 
    csv2 = csv.reader(file2, delimiter=';') 

    lookup = { line[0] : line[1:] for line in csv1 } 
    joined = [ [uname, uid] + lookup[uname] for (uname, uid) in csv2 ] 

print joined 

(en supposant la version Python2.7)

BTW: la première colonne a l'index 0, pas 1.

Questions connexes