【问题标题】:Problem with nested for loops嵌套for循环的问题
【发布时间】:2010-07-20 17:19:08
【问题描述】:

我必须读取两个 csv 文件,合并行并将结果写入第三个 csv 文件。 第一个 csv 文件在第一列中有五行用户名。(总共 25 列) 第二个 csv 文件有五行,第一列中的用户名和第二列中的用户 ID。(只有 2 列)

第三个 csv 文件将包含 username+userid 和第一个文件的所有剩余 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

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

【问题讨论】:

    标签: python


    【解决方案1】:

    这是因为您在第一遍中读取了 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?

    希望对您有所帮助。 :)

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

        (假设Python版本2.7

        顺便说一句:第一列的索引为 0,而不是 1。

        【讨论】:

          【解决方案4】:

          这可能很容易解决...尝试将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
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-01-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多