2

背景:

我在尝试搜索某些 CSV 文件时遇到问题。我浏览了 python 文档:http ://docs.python.org/2/library/csv.html 关于csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)csv 模块的对象。

我的理解是,csv.DictReader假设文件的第一行/第一行是字段名,但是,我的 csv 字典文件只是以“key”、“value”开头并持续至少 500,000 行。

我的程序将询问用户他们正在寻找的标题(因此是键),并使用打印功能将值(即第二列)显示到屏幕上。我的问题是如何使用 csv.dictreader 来搜索特定的键,并打印它的值。

示例数据: 以下是 csv 文件及其内容的示例...

"Mamer","285713:13"

"Champhol","461034:2"

"Station Palais","972811:0"

所以如果我想找到“Station Palais”(输入),我的输出将是 972811:0。我能够操作字符串并创建整个程序,我只需要 csv.dictreader 的帮助。感谢任何帮助。

编辑部分:

    import csv

    def main():
        with open('anchor_summary2.csv', 'rb') as file_data:
        list_of_stuff = []
        reader = csv.DictReader(file_data, ("title", "value"))
            for i in reader:
              list_of_stuff.append(i)
            print list_of_stuff

    main()
4

2 回答 2

2

您链接到的文档提供了一半的答案:

csv.DictReader( csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds )

[...] 将读取的信息映射到一个 dict,其键由可选的fieldnames参数给出。如果省略fieldnames参数,则csvfile第一行中的值将用作字段名。

似乎如果fieldnames传递了参数,给定文件的第一条记录将不会被解释为标题(将使用参数代替)。

# file_data is the text of the file, not the filename
reader = csv.DictReader(file_data, ("title", "value"))
for i in reader:
  list_of_stuff.append(i)

这将(显然;我一直遇到麻烦)产生以下数据结构:

[{"title": "Mamer", "value": "285713:13"},
 {"title": "Champhol", "value": "461034:2"},
 {"title": "Station Palais", "value": "972811:0"}]

可能需要通过以下方式将其进一步按摩到标题到值的映射中:

data = {}
for i in list_of_stuff:
  data[i["title"]] = i["value"]

现在只需使用 的键和值data来完成您的任务。


这里是字典理解:

data = {row["title"]: row["value"] for row in csv.DictReader(file_data, ("title", "value"))}
于 2013-05-20T02:22:22.907 回答
2

当前接受的答案很好,但是有一种更直接的方式来获取数据。dict()Python 中的构造函数可以采用任何可迭代对象。

此外,您的代码在 Python 3 上可能存在问题,因为 Python 3 的 csv 模块要求文件以文本模式打开,而不是二进制模式。io.open您可以通过使用而不是使您的代码与 2 和 3 兼容open

import csv
import io

with io.open('anchor_summary2.csv', 'r', newline='', encoding='utf-8') as f:
    data = dict(csv.reader(f))

print(data['Champhol'])

作为警告,如果您的 csv 文件在第一列中有两行具有相同值,则后面的值将覆盖前面的值。(其他发布的解决方案也是如此。)

如果您的程序真的只应该打印结果,那么真的没有理由构建一个键控字典。

import csv
import io


# Python 2/3 compat
try:
    input = raw_input
except NameError:
    pass


def main():
    # Case-insensitive & leading/trailing whitespace insensitive
    user_city = input('Enter a city: ').strip().lower()

    with io.open('anchor_summary2.csv', 'r', newline='', encoding='utf-8') as f:
        for city, value in csv.reader(f):
            if user_city == city.lower():
                print(value)
                break
        else:
            print("City not found.")

if __name __ == '__main__':
    main()

这种技术的优点是 csv 不会加载到内存中,并且数据只迭代一次。我还在两个键上的调用中添加了一些代码,lower以使匹配不区分大小写。另一个优点是,如果用户请求的城市位于文件顶部附近,它几乎会立即返回并停止查看文件。

尽管如此,如果搜索性能是您的首要考虑因素,您应该考虑将数据存储在数据库中。

于 2017-07-18T14:03:21.413 回答