2012-11-04 5 views
0

J'ai un dictionnaire où item_dictionary[0] correspond à data[0], et item_dictionary[1] correspond à .Ecrire plusieurs fichiers .csv

item_dictionary = {'10350':'cat', '560':'dog'} 
names = item_dictionary.values() 

data = [[1, 2, 3, 4], [5, 6, 7]] 

J'ai essayé d'écrire les articles dans data[0] et à différents fichiers .csv comme ceci:

def writer(item): 
    q = data.index(item)  
    myfile = open('%r.csv', 'wb') % names[q] 
    wr = csv.writer(myfile) 
    wr.writerows(data[q]) 
    myfile.close() 

z = [writer(x) for x in data] 

Cela renvoie l'erreur:

Traceback (most recent call last):
File "", line 1, in
File "", line 3, in writer
TypeError: unsupported operand type(s) for %: 'file' and 'str'`.

Je pense pour la 'str' partie de l'erreur est que names[q] renvoie, disons, 'cat' au lieu de cat. Cependant, je ne sais pas quel type d'opérande utiliser et je ne sais pas comment contourner le problème str, donc quelqu'un pourrait-il m'aider s'il vous plaît? Merci.

+2

Attention: en Python, les dictionnaires ne sont pas ordonnés et l'ordre dans lequel les éléments apparaissent dans '.values ​​()' est arbitraire. Il n'est donc pas vrai que "item_dictionary [0] correspond à data [0], et item_dictionary [1] correspond à data [1]" - il n'y a pas * 'item_dictionary [0]'. (Essayez-le et voyez - vous obtiendrez une KeyError.) Il existe un type de dictionnaire ordonné séparé, mais ce n'est pas ce que vous utilisez. – DSM

+0

Merci pour les heads up. –

Répondre

3

open('%r.csv', 'wb') % names[q] doit être open('%r.csv' % names[q], 'wb'). Dans le premier cas, vous ouvrez un fichier nommé "% r.csv" pour écrire en mode binaire, puis essayez de moduler l'objet fichier avec le contenu names[q]. file objets ne prennent pas en charge l'opérateur modulo et ainsi vous obtenez le TypeError.

Dans ce dernier cas, nous appelons la méthode format de la chaîne %r.csv avec l'opérateur de module résultant en une chaîne transmise à la fonction open.


En aparté, vous voudrez peut-être envisager une autre façon d'associer des noms aux données - vous pourrait les noms des magasins à côté de vos données soit tuples, des dictionnaires ou des instances de classe:

# Tuples 
data = [("cat", [1, 2, 3, 4]), ("dog", [5, 6, 7])] 
for name, file_data in data: 
    print name, "=>", file_data 

# Dictionary (assumes only one instance of name per data point) 
data = {"cat": [1, 2, 3, 4], "dog": [5, 6, 7]} 
for name, file_data in data.items(): 
    print name, "=>", file_data 

# Class instances (ignore this one if you haven't done any OO before) 
# (You don't need it if you don't *know* you need it). 
class MyDataType(object): 
    def __init__(self, name, data): 
     self.name = name 
     self.data = data 

data = [MyDataType("cat", [1, 2, 3, 4]), MyDataType("dog", [5, 6, 7])] 
for data_point in data: 
    print data_point.name, "=>", data_point.data 
+0

Ok. Cela a fixé un problème seulement pour révéler une autre faille dans mon code. Je reçois maintenant 'retraçage (appel le plus récent en dernier): Fichier "", ligne 1, dans Fichier "", ligne 5, en écrivain _csv.Error: séquence expected'. –

+0

@ user1709173 - la fonction d'écriture csv attend une liste * de listes * (ou au moins une itérable * d'iterables *) qui lui est transmise lorsqu'elle essaie de faire ce qui suit 'pour row in data: pour data_point in row: write_data (point_données) 'il se trouve en train d'essayer d'itérer sur' int's et souffle. ('pour row dans [1, 2, 3, 4]: pour data_point dans 1: # BOOM! (1 n'est pas itérable)') –

+0

Donc, si 'data' est la liste des listes, comment puis-je créer un fichier csv qui ne contient qu'un élément de' data' au lieu des deux? –

Questions connexes