Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何根据给定列表中的单词合并两个csv文件?_Python_Loops_Csv_For Loop - Fatal编程技术网

Python 如何根据给定列表中的单词合并两个csv文件?

Python 如何根据给定列表中的单词合并两个csv文件?,python,loops,csv,for-loop,Python,Loops,Csv,For Loop,我有两个csv文件,每个都是这种格式 file1 zip name score 23431 david 12 23231 rob 45 33441 hary 23 98901 rgrg 55 file2 zip1 name1 score1 23433 david 12 23245

我有两个csv文件,每个都是这种格式

file1
zip     name    score                
23431   david   12                  
23231   rob     45
33441   hary    23
98901   rgrg    55  


file2
zip1    name1   score1                
23433   david   12                  
23245   stel    45
33478   hary    23
98988   rob     55  
12121   jass    33
我有一张名单,上面有名字,像这样

lista = ['harry', 'rob', 'wine', 'david', 'jass']
最终的csv文件应如下所示:

name    zip     score       zip1     score1
harry   x       x           x           x
rob     23231   45          98988       55
wine    x       x           x           x
david   23431   12          23433       12
jass    x       x           12121       33
这意味着,如果列表中的任何名称位于任何一个csv文件中,那么我们应该将其与zip和分数一起包含在新的csv文件中。否则我们应该在里面打印“x”

这就是我到目前为止所做的:

import csv
with open('file1.csv', 'r') as input1, open('file2.csv', 'r') as input2, open('merge_final.csv', 'w') as output:
    writer = csv.writer(output)
    reader1 = csv.reader(input1)
    eader2 = csv.reader(input2)

    lista = ['harry', 'rob', 'wine', 'david', 'jass']
    writer.writerow(['name','zip','score','zip1','score'])

        for i in lista:     
            for row in list(reader1):
                rev = row[1]
                if i in rev:
                    score = row[2]
                    zip = row[0]    
                else:
                    score = 'x'
                    zip = 'x'               
            for row in list(reader2):
                rev = row[1]
                if i in rev:
                    score1 = row[2]
                    zip1 = row[0]
                else:
                    score1 = 'x'
                    zip1 = 'x'  
            writer.writerow([i, score, zip, score1, zip1])
此代码未按预期工作。这是我用这段代码得到的输出

name    zip     score       zip1     score1
harry   x       x           x           x
rob     x      x            x            x
wine    x       x           x           x
david   x       x           x           x
jass    x       x           x           x

即使有很多常用词,最终合并的csv文件中也只会打印“x”。我认为问题在于循环。但是,我似乎没有弄明白问题所在

首先,第一次调用
list(readerX)
将耗尽迭代器,迭代器是文件句柄

其次,
rev
应该已经是
名称
,因此检查是否包含以下等式:
如果name==rev

第三,除了每个文件中的姓氏之外,您通常会得到'x',因为您将文件迭代到最后,只有最后一行才真正重要。您应该在找到名称后立即
中断内部循环,但只有在迭代整个文件而未找到名称后才设置默认值

此外,重复迭代这两个文件是非常糟糕的性能。您最好将这两个文件加载到一个永久性的数据结构中,以更快的速度查找,就像使用名称作为键的嵌套
dict

d1 = {row[1]: {'zip': row[0], 'score': row[2]} for row in reader1}
d2 = {row[1]: {'zip': row[0], 'score': row[2]} for row in reader2}
#   {'david': {'zip': 23431, 'score: 12, ...}    

for name in lista:
    if name in d1 or name in d2:
        writer.writerow([
            name,
            d1.get(name, {}).get('zip', 'x'),
            d1.get(name, {}).get('score', 'x'),
            d2.get(name, {}).get('zip', 'x'),
            d2.get(name, {}).get('score', 'x'),
        ])
要使您自己的方法发挥作用,请进行如下更改,但请注意,由于嵌套循环的存在,这对较大数据的性能很差:

# next(reader1)  # skip the header line if necessary
lst1 = list(reader1)  # load all the data into a list beforehand ...
for i in lista:  
    for row in lst1:  # ... that you can repeatedly iterate
        rev = row[1]
        if i == rev:  # compare for equality
            score = row[2]
            zip = row[0]   
            break  # <- you found the name, so end the loop! 
    else:  # note the indentation: this is a for-else-loop, not an if-else
        # the else-part is only executed if the for loop was NOT break'ed
        score = 'x'
        zip = 'x'  
#下一步(reader1)#必要时跳过标题行
lst1=list(reader1)#预先将所有数据加载到列表中。。。
对于lista中的我:
对于lst1中的行:#。。。可以重复迭代的
rev=第[1]行
如果i==rev:#比较是否相等
分数=第[2]行
zip=行[0]

break#首先,第一次调用
list(readerX)
将耗尽迭代器,即文件句柄

其次,
rev
应该已经是
名称
,因此检查是否包含以下等式:
如果name==rev

第三,除了每个文件中的姓氏之外,您通常会得到'x',因为您将文件迭代到最后,只有最后一行才真正重要。您应该在找到名称后立即
中断内部循环,但只有在迭代整个文件而未找到名称后才设置默认值

此外,重复迭代这两个文件是非常糟糕的性能。您最好将这两个文件加载到一个永久性的数据结构中,以更快的速度查找,就像使用名称作为键的嵌套
dict

d1 = {row[1]: {'zip': row[0], 'score': row[2]} for row in reader1}
d2 = {row[1]: {'zip': row[0], 'score': row[2]} for row in reader2}
#   {'david': {'zip': 23431, 'score: 12, ...}    

for name in lista:
    if name in d1 or name in d2:
        writer.writerow([
            name,
            d1.get(name, {}).get('zip', 'x'),
            d1.get(name, {}).get('score', 'x'),
            d2.get(name, {}).get('zip', 'x'),
            d2.get(name, {}).get('score', 'x'),
        ])
要使您自己的方法发挥作用,请进行如下更改,但请注意,由于嵌套循环的存在,这对较大数据的性能很差:

# next(reader1)  # skip the header line if necessary
lst1 = list(reader1)  # load all the data into a list beforehand ...
for i in lista:  
    for row in lst1:  # ... that you can repeatedly iterate
        rev = row[1]
        if i == rev:  # compare for equality
            score = row[2]
            zip = row[0]   
            break  # <- you found the name, so end the loop! 
    else:  # note the indentation: this is a for-else-loop, not an if-else
        # the else-part is only executed if the for loop was NOT break'ed
        score = 'x'
        zip = 'x'  
#下一步(reader1)#必要时跳过标题行
lst1=list(reader1)#预先将所有数据加载到列表中。。。
对于lista中的我:
对于lst1中的行:#。。。可以重复迭代的
rev=第[1]行
如果i==rev:#比较是否相等
分数=第[2]行
zip=行[0]

break#您不认为最好将这两个文件读入一个嵌套字典,其中名称是键,值是带有键“zip”、“zip1”、“score”和“score1”的字典吗

    {'hary' : 
        {'zip1':33478, 
         'zip':33441 ,
         'score':23,
         'score1':23 }
    }

然后在列表中迭代并打印“x”,无论键是否存在,您不认为最好将这两个文件读入一个嵌套字典,其中名称为键,值为带有键“zip”、“zip1”、“score”和“score1”的字典吗

    {'hary' : 
        {'zip1':33478, 
         'zip':33441 ,
         'score':23,
         'score1':23 }
    }

然后在列表中迭代并打印“x”,以查找任何不存在的键

上述代码中的错误:

  • 列表的第一个循环(reader1)耗尽迭代器,迭代器是文件句柄。因此,当“lista”的下一次迭代开始时,reader1为空,len=0。
    将数据存储在列表或字典中,而不是重复迭代文件句柄
  • 当i与rev匹配时,如果(i在rev中),您继续迭代文件的其余部分,这会导致zip和score的值重置为“x”,因为下一次迭代“i在rev中”将给出False。您需要拆下else零件以更正此问题。相反,在lista中i的后面声明zip,并将其得分为“x”:

  • 上述代码中的错误:

  • 列表的第一个循环(reader1)耗尽迭代器,迭代器是文件句柄。因此,当“lista”的下一次迭代开始时,reader1为空,len=0。
    将数据存储在列表或字典中,而不是重复迭代文件句柄
  • 当i与rev匹配时,如果(i在rev中),您继续迭代文件的其余部分,这会导致zip和score的值重置为“x”,因为下一次迭代“i在rev中”将给出False。您需要拆下else零件以更正此问题。相反,在lista中i的后面声明zip,并将其得分为“x”:

  • 谢谢另外,请您指出我上面代码中的错误(除了呼叫列表(readerX))好吗?这样我就可以从错误中吸取教训,不再重蹈覆辙。谢谢你的及时回复。我还通过使用
    if I==rev
    尝试了该代码,但输出没有改变(整个文件都打印了x)。请允许我再问一个问题,我想我的问题的关键是在这句话中,如果两个文件中都没有名字,那么上一次迭代中的zip和score变量不会改变,并且会再次写入。。。我应该如何实施它?对不起,我刚开始学习python不久。谢谢!另外,请您指出我上面代码中的错误(除了呼叫列表(readerX))好吗?这样我才能从错误中吸取教训,不再重蹈覆辙。谢谢你的及时提醒