我正在尝试使用python 2.7从CSV中的所有行返回一个项目,该项目包含与字典中每个键的匹配。
我尝试过以下代码
with open(r"root\to\file", "r") as inFile:
for k in myDict.keys():
reader = csv.reader(inFile)
result = [row[11] for row in reader if row[3] == k]
print(result)
作为输出,我得到一个成功的列表,然后是正确的空列表数。
有谁可以告诉我为什么它只适用于第一把钥匙?
提前致谢
答案 0 :(得分:0)
任何人都可以告诉我为什么它只适用于第一个键吗?
reader = csv.reader(inFile)打开文件并开始从头到尾重新播放它。然后它会将光标留在最后。在接下来的迭代中,没有什么可读的。
如何解决此问题(快速修复版本)?
with open(r"root\to\file", "r") as inFile:
for k in myDict.keys():
reader = csv.reader(inFile)
inFile.seek(0) # move cursor to start
result = [row[11] for row in reader if row[3] == k]
print(result)
我将举例说明我的意思。首先,让我向您提供一些我写入文件的示例数据(csv-format)。
import csv
dict_ = {"1":1, "2":3}
data = """date,id,weight
01/01/1991,1,293
01/02/1991,2,291
01/03/1991,3,289
"""
with open("output.txt","wt") as f:
f.write(data)
非工作示例:
with open("output.txt") as f:
for keys in dict_:
reader = csv.reader(f) # <-- Opens file and reads it (cursor in end)
print([i for i in reader])
## Output
# >> [['date', 'id', 'weight'], ['01/01/1991', '1', '293'], ['01/02/1991', '2', '291'], ['01/03/1991', '3', '289']]
# >> []
而是使用它:
with open("output.txt") as f:
for keys in dict_:
reader = csv.reader(f) # <-- Opens file and reads it (cursor in end)
f.seek(0) # <-- Return cursor to 0 (cursor is now in the start)
print([i for i in reader])
## Output
# >> [['date', 'id', 'weight'], ['01/01/1991', '1', '293'], ['01/02/1991', '2', '291'], ['01/03/1991', '3', '289']]
# >> [['date', 'id', 'weight'], ['01/01/1991', '1', '293'], ['01/02/1991', '2', '291'], ['01/03/1991', '3', '289']]
或者首先将其读取到局部变量:
with open("output.txt") as f:
csvdata = list(csv.reader(f)) #or this
for key in dict_.keys():
[print(i) for i in csvdata if i[1] == key]
## Output
# >> ['01/01/1991', '1', '293']
# >> ['01/02/1991', '2', '291']
答案 1 :(得分:0)
每次都需要重新打开文件。因此,反转with和for语句。
为了提高效率,我建议使用pandas来读取csv,这样你就可以多次查询结果数据帧。
答案 2 :(得分:0)
它仅用于第一个键的原因是,当读取文件时,在读取开始时和文件末尾有文件位置在文件的开头。阅读结束了。在第一个键之后,阅读器已到达文件的末尾,并且不会自动返回到文件的开头。
我至少看到了三个解决方案
加载所有行的列表
with open(r"root\to\file", "r") as inFile:
row_list = list(csv.reader(inFile))
for k in myDict:
result = [row[11] for row in row_list if row[3] == k]
print(result)
仅在字典中存储匹配的项目
这是我最喜欢的解决方案。每行只检查一次
from collections import defaultdict
result_dict = defaultdict(list)
with open(r"root\to\file", "r") as inFile:
for row in csv.reader(infile):
if row[3] in myDict:
result_dict[row[3]].append(row[11])
for k, result in result_dict.items():
print(k, result)
在每次迭代时返回文件的开头
优点是我们不需要存储任何东西,但这是不寻常的
执行许多file.seek
操作,所以我更喜欢存储行
如果csv文件的大小不是太大。
with open(r"root\to\file", "r") as inFile:
reader = csv.reader(inFile)
for k in myDict:
inFile.seek(0)
result = [row[11] for row in reader if row[3] == k]
print(result)