通过匹配字典键python从csv获取行

时间:2017-07-25 06:02:48

标签: python csv dictionary

我正在尝试使用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)  

作为输出,我得到一个成功的列表,然后是正确的空列表数。

有谁可以告诉我为什么它只适用于第一把钥匙?

提前致谢

3 个答案:

答案 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)