2010-07-20 117 views
2

我必须读取两个csv文件,合并该行并将结果写入第三个csv文件。 第一csv文件有五列与用户名在第一colunm。(总共25 colunm) 第二csv文件有五排在在第二colunm第一colunm和用户ID的用户名。(仅2 colunm)嵌套for循环的问题

第三个csv文件将包含用户名+ useridand第一个文件的所有剩余的24列。

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 

结果:

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 

我为什么= 2的seconf for循环后什么也不做? 我希望有i = 2,j = 0到6,i = 3 j = 0 ro 6,...

回答

1

因为一旦csv.reader达到文件的末尾,它将永远不会再执行。

对于像这样的小数据集,您可以轻松地将数据读入列表或字典并对其进行迭代。

0

这可能是一个简单的办法......请尝试移动声明Info_Client_source2进入第一循环:

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

这是因为你在第一遍读出你的StringIO对象的全部内容,留下光标在字符串的末尾。第二遍,没有什么可读的,所以你最终会得到一个空的阅读器。

此外,对于循环的每个内部迭代调用csv.reader()可能不是一个好主意。让我重组你的代码,然后解释我的变化:

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 

变化:

  • 我已经去创建一个StringIO对象的多余步骤;你可以传递一个标准的文件句柄到csv.reader(),它会正常工作。 (如果有创建这些StringIO对象的原因,请随时将其添加回...)
  • 我已经将阅读器的初始化移至for循环之外。虽然source1在外部循环中被初始化是可以的,但在内部循环中初始化source2会非常低效。
  • 最重要的是,调用data2.seek(0)将重置基础文件句柄上的光标,这将允许您重复读取data2。

这里有SO一个类似的问题,这可能会更好地说明这个想法:

StackOverflow: Reading from CSVs in Python repeatedly?

希望它能帮助。:)

1

更多pythonic将是:

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 

(假设2.7Python版本)

顺便说一句:第一列具有索引0,而不是1