我是Stackoverflow的新手,也是Python的新手。我尝试在网站上搜索此问题的答案,但未找到与csv和txt文件之间的匹配值相关的问题。
我正在编写一个简单的Python脚本,它从大型csv文件中读取一行(~600k行),从该行中获取值,分配给变量,然后使用该变量尝试查找匹配来自大型txt文件的值(~1.8MM行)。它不起作用,我不确定原因。以下是source.csv
文件的摘录:
DocNo,Title,DOI
1,"Title One",10.1080/02724634.2016.1269539
2,"Title Two",10.1002/2015ja021888
3,"Title Three",10.1016/j.palaeo.2016.09.019
这是lookup.txt
文件中的一个片段(请注意它由\t
分隔):
DOI 10.1016/j.palaeo.2016.09.019 M First
DOI 10.1016/j.radmeas.2015.12.002 M First
DOI 10.1097/SCS.0000000000002859 M First
以下是有问题的代码:
import csv
with open('source.csv', newline='', encoding = "ISO-8859-1") as f, open('lookup.txt', 'r') as i:
reader = csv.reader(f, dialect='excel')
counter = 0
for line in i:
for row in reader:
doi = row[2]
doi = str(doi) # I think this might actually be redundant...
if doi in line:
# This will eventually do more interesting things, but right now it's just a test
print(doi)
break
else:
# This will be removed--is also just a test (so I can watch progress)
print(counter)
counter += 1
目前,当它运行时,它只计算行数,即使每个文件中都匹配doi
。
令人抓狂的是,当我给doi
一个硬编码值时,它会按原样执行。这让我觉得doi
中的斜杠会以某种方式破坏事物,或者我需要转换doi
变量的数据类型。
例如,这有效:
doi = "10.1016/j.palaeo.2016.09.019"
for line in i:
if doi in line:
print(doi)
break
else:
print(counter)
counter += 1
在此先感谢您的帮助,我的智慧结束了!
答案 0 :(得分:1)
你的问题是重复for line in i:
并不会从每个循环的开头重新开始,而是继续前进到最后一次调用break
时的状态。如果查找文件i
中的任何行没有匹配,您将完全有效地浏览查找文件,然后对for line in i:
的所有调用都不会执行任何操作(空循环)。
作为第一步,您可能希望将查找行保留在列表中。通过解析行将其转换为查找字典可能是下一步。
以下是对所发生情况的演示:
!cat 1.txt
row1
row2
row3
!cat 2.txt
row A
row B
row C
with open('1.txt', 'r') as i, open('2.txt', 'r') as j:
for irow in i:
print "irow", irow.strip()
for jrow in j:
print "jrow", jrow.strip()
irow row1
jrow row A
jrow row B
jrow row C
irow row2
irow row3
答案 1 :(得分:0)
你可以试试这个:
import csv
data = csv.reader(open('data1.csv'))
data1 = [i.strip('\n').split()[1] for i in open('data2.txt')]
file_data = [i[-1] for i in data if i[-1] in data1]
提供的示例文件的输出:
['10.1016/j.palaeo.2016.09.019']