使用Python从CSV文件创建列表

2 投票
3 回答
14932 浏览
提问于 2025-04-16 06:45

我现在有一个Python脚本,基本上能完成我想要的功能……它可以打开用户指定的CSV文件,把文件分成不同的“池”,然后再把这些池重新制作成各自的文件,并加上合适的标题。我的唯一问题是,我想把池的列表从固定的改成可变的,但遇到了一些问题。

池的列表在CSV文件的第二列,并且可以重复。目前这个设置下,系统可能会生成一些“空”文件,里面除了标题外没有任何数据。

几点说明:是的,我知道拼写不太完美,也知道我的一些评论可能有点偏离主题。

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 -----

编辑:因为有些问题出现了

写这段代码的原因是:我每天都会生成报告,其中一部分需要手动处理,就是把这些报告分成不同的池报告。我创建这个脚本是为了能快速选择文件,并把它们迅速分开成各自的文件。

主CSV文件的长度大约在50到100项之间,总共有25列,而池的信息总是在第二列。不一定所有的池都会一直列出,而且同一个池可能会出现多次。

我尝试了几种不同的循环,下面是其中一个:

pools = []
for line in file(open(filename,'rb')):
line = line.split()
x = line[1]
pools.append(x)

但我在这段代码中遇到了列表错误。

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

3 个回答

0

你的代码如果去掉那些exec语句,会更容易阅读。看起来你是用它们来声明所有的变量,其实你可以这样声明一个池的列表:

pool_lists = [[] for p in pools]

这是我对你所说的“我想把池列表从静态变成动态”的最佳猜测。当你这样做时,你会得到一个列表的列表,长度和池是一样的。

2

你能简单描述一下你的CSV文件吗?

有一个建议是把

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

改成更符合Python风格的写法:

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

一般来说,使用eval/exec是不太好的,直接通过字典来循环会简单得多。例如,可以通过pool_dict['A']、pool_dict['1']来访问变量,或者像这样循环访问所有变量:

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

编辑:现在看到CSV数据了,可以试试这样的做法:

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)
4

如果我理解得没错,你想要实现的目标可以用这个方法来解决:

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)

编辑:一开始我误解了头部和池子的概念,试着纠正这个问题。

编辑2:我修正了池子的创建方式,现在是根据文件中的值动态生成的。

如果不是这样,请提供更多关于你问题的细节……

撰写回答