2010-11-08 24 views
1

J'ai un script Python jusqu'ici qui fait ce que je ... Ouvre le CSV Défini par l'utilisateur, divise le fichier en différents "pools" prédéfinis et les refait en leurs propres fichiers, avec des en-têtes appropriés. Mon seul problème est que je veux changer la liste de Pool d'une statique à une variable; et avoir quelques problèmes.Création d'une liste à partir d'un fichier CSV en utilisant Python

La liste de pool se trouve dans le CSV lui-même, dans la colonne 2. et peut être dupliquée. À l'heure actuelle, avec cette configuration, le système peut créer des fichiers «morts» sans données en dehors de l'en-tête.

Quelques notes: Oui, je sais l'orthographe est pas parfait et oui je sais ce que certains de mes commentaires sont un peu hors

import csv 
#used to read ane make CSV's 
import time 
#used to timestamp files 
import tkFileDialog 
#used to allow user input 
filename = tkFileDialog.askopenfilename(defaultextension = ".csv") 
#Only user imput to locate the file it self 
csvfile = [] 
#Declairs csvfile as a empty list 
pools = ["1","2","4","6","9","A","B","D","E","F","I","K","L","M","N","O","P","W","Y"] 
#declairs hte pools list for known pools 
for i in pools: 
    #uses the Pools List and makes a large number of variables 
    exec("pool"+i+"=[]") 
reader = csv.reader(open(filename, "rb"), delimiter = ',') 
#Opens the CSV for the reader to use 
for row in reader: 
    csvfile.append(row) 
    #dumps the CSV into a varilable 
    headers=[] 
    #declairs headers as empty list 
    headers.append(csvfile[0]) 
    #appends the first row to the header variable 
for row in csvfile: 
    pool = str(row[1]).capitalize() 
    #Checks to make sure all pools in the main data are capitalized 
    if pool in pools: 
     exec("pool"+pool+".append(row)") 
     #finds the pool list and appends the new item into the variable list 
    else: 
     pass 
for i in pools: 
    exec("wp=csv.writer(open('pool "+i+" "+time.strftime("%Y%m%d")+".csv','wb'),)") 
    wp.writerows(headers) 
    #Adds the header row 
    exec("wp.writerows(pool"+i+")") 
    #Created the CSV with a timestamp useing the pool list 
    #-----Needs Headers writen in on each file ----- 

EDIT: Comme il y a eu quelques questions

Raison de le code: J'ai des rapports quotidiens qui sont générés, Une partie de ces rapports qui nécessitent un processus manuel est la division de ces rapports en différents rapports de pool. Je créais ce script afin que je puisse rapidement sélectionner le fichier et les partager rapidement dans leurs propres fichiers.

Le fichier CSV principal peut contenir de 50 à 100 éléments, il contient 25 colonnes au total et le pool est toujours répertorié dans la deuxième colonne. Tous les pools ne seront pas listés tout le temps, et les pools apparaîtront plus d'une fois.

J'ai déjà essayé plusieurs boucles différentes; une est la suivante

pools = [] pour la ligne dans le fichier (ouverte (nom de fichier, 'rb')): line = line.split() x = ligne [1] pools.append (x)

Mais j'obtiens une erreur de liste avec ceci.

Un exemple du CSV:

Ticket Pool Date Column 4 Column 5 

1 A 11/8/2010 etc etc 

2 A 11/8/2010 etc etc 

3 1 11/8/2010 etc etc 

4 6 11/8/2010 etc etc 

5 B 11/8/2010 etc etc 

6 A 11/8/2010 etc etc 

7 1 11/8/2010 etc etc 

8 2 11/8/2010 etc etc 

9 2 11/8/2010 etc etc 

10 1 11/8/2010 etc etc 
+4

quel cauchemar – SilentGhost

+2

je suggère que vous publiez votre intention. Cela semble très compliqué et il se peut que votre intention puisse être atteinte par des moyens simples. Je suis d'accord avec SilentGhost à ce sujet. – pyfunc

+0

dStulle était capable de me montrer ce que je devais faire. Je vous remercie! – Talauna

Répondre

4

Si je comprends bien ce que vous whan't pour réaliser ici ce pourrait être aussi une solution:

import csv 
import time 
import tkFileDialog 

filename = tkFileDialog.askopenfilename(defaultextension = ".csv") 

reader = csv.reader(open(filename, "rb"), delimiter = ',') 

headders = reader.next() 

pool_dict = {} 

for row in reader: 
    if not pool_dict.has_key(row[1]): 
     pool_dict[row[1]] = [] 
    pool_dict[row[1]].append(row) 

for key, val in pool_dict.items(): 
    wp = csv.writer(open('pool ' +key+ ' '+time.strftime("%Y%m%d")+'.csv','wb'),) 
    wp.writerow(headders) 
    wp.writerows(val) 

EDIT: mal compris les en-têtes et piscines chose en premier lieu et a essayé de corriger le problème.

EDIT 2: correction du pool à créer dynamiquement à partir des valeurs trouvées dans le fichier.

Dans le cas contraire, s'il vous plaît fournir plus de détails sur votre problème ...

+0

C'est beaucoup plus propre que ce que j'ai fait. Seuls les problèmes que je rencontre avec cela, c'est qu'il tire les 25 en-têtes et pas la liste de la piscine, et il crée 25 fichiers pour chaque en-tête ... – Talauna

+0

alors où voulez-vous obtenir votre ligne de piscine? Ou est-ce censé être dans le code? – dStulle

+0

Vous avez la bonne idée; mais le problème que j'ai avec la liste des pools dans une liste comme ceci est que s'il n'y a aucune valeur pour ce pool, il crée toujours le fichier, qui a juste des en-têtes; pas de données. – Talauna

2

Pouvez-vous décrire votre fichier CSV un peu?

Une suggestion est de changer

for i in pools: 
#uses the Pools List and makes a large number of variables 
    exec("pool"+i+"=[]") 

à la forme plus pythonique:

pool_dict = {} 
for i in pools: 
    pool_dict[i] = [] 

En général sa mauvaise à utiliser eval/exec et beaucoup plus facile à dire boucle à travers un dictionnaire. Par exemple, les variables d'accès par pool_dict [ 'A'], pool_dict [ '1'] ou d'une boucle par tous comme

for key,val in pool_dict.items(): 
    val.append(...) 

EDIT: Maintenant voir les données CSV, essayez quelque chose comme ceci:

for row in reader: 
    if row[0] == 'Ticket': 
     header = row 
    else: 
     cur_pool = row[1].capitalize() 
     if not pool_dict.has_key(cur_pool): 
      pool_dict[cur_pool] = [row,] 
     else: 
      pool_dict[cur_pool].append(row) 

for p, pool_vals in pool_dict.items: 
    with open('pool'+p+'_'+time.strftime("%Y%m%d")+'.csv','wb'),) as fp: 
     wp = csv.writer(fp) 
     wp.writerow(header) 
     wp.writerows(pool_vals) 
+0

Si, pour une raison quelconque, la valeur du pool est "Pool", ces lignes seront ignorées et le dernier d'entre elles deviendra le nouvel en-tête des fichiers de sortie. Je l'admets, il est peu probable ... – dStulle

+0

Ok a changé pour vérifier que la ligne [0] est "Ticket" comme probablement pas un # ticket valide. Ne pensez pas qu'il est prudent de supposer que l'en-tête est toujours la ligne zéro et n'est pas répété comme une autre ligne dans le fichier. Mais; cela dépend finalement des données; et est assez mineur. (A noté au moins 3 bugs dans mon code si - négligence (non == dans la comparaison, fait l'en-tête juste la rangée [1] et a essayé d'ajouter à la dict pas pool_dict [cur_pool]).) Aussi sa bonne pratique à utilisez l'option open avec open() comme idiome fp, car cela garantit que le fichier est correctement fermé, même sur les exceptions. –

0

Vous code serait beaucoup plus facile à lire sans tous ces execs. Il semble que vous les avez utilisés pour déclarer toutes vos variables, alors qu'en fait, vous pouvez déclarer une liste des piscines comme ceci:

pool_lists = [[] for p in pools] 

Ceci est ma meilleure estimation pour ce que vous entendez par « Je veux changer la piscine liste d'une statique à une variable. " Lorsque vous faites cela, vous aurez une liste de listes, de la même longueur que les pools.