将 csv.DictReader 对象转换为字典列表?

Posted

技术标签:

【中文标题】将 csv.DictReader 对象转换为字典列表?【英文标题】:Convert a csv.DictReader object to a list of dictionaries? 【发布时间】:2015-06-08 14:04:19 【问题描述】:

一个csv文件names.csv有内容:

first_name last_name
Baked Beans
Lovely Spam
Wonderful Spam

我想将它读入字典列表,第一行包含键:

>>> import csv
>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile)
...     for row in reader:
...         print(row['first_name'], row['last_name'])
...
Baked Beans
Lovely Spam
Wonderful Spam

但是reader的类型是csv.DictReader吗? 如何将reader 转换为字典列表? 谢谢。

【问题讨论】:

【参考方案1】:

csv.DictReader 创建一个 dictreader 对象,如标题中所述。此对象仅在文件打开且无法切片时可用。

根据标题将对象转换为列表......

list_of_dicts = list(your_dictreader_object)

【讨论】:

【参考方案2】:

创建函数

import csv


def csv_to_dict(filename):
    result_list=[]
    with open(filename) as file_obj:
        reader = csv.DictReader(file_obj, delimiter=delimiter)
        for row in reader:
            result_list.append(dict(row))
    return result_list

并使用它:

list_of_dicts = csv_to_dict('names.csv')

【讨论】:

【参考方案3】:
import csv
with open("in.csv") as csvfile:
    reader = csv.DictReader(csvfile,delimiter=" ")
    print(list(reader))
['first_name': 'Baked', 'last_name': 'Beans', 'first_name': 'Lovely', 'last_name': 'Spam', 'first_name': 'Wonderful', 'last_name': 'Spam']

如果分隔符实际上不是,,则需要指定" " 或其他任何内容。

为了消除任何混淆,该代码也适用于 python3.6,唯一的区别是使用 DictReader 默认情况下会给出 Orderdicts:

In [1]: import csv
   ...: with open("in.csv") as csvfile:
   ...:     reader = csv.DictReader(csvfile, delimiter=" ")
   ...:     print(list(reader))
   ...:     
[OrderedDict([('first_name', 'Baked'), ('last_name', 'Beans')]), OrderedDict([('first_name', 'Lovely'), ('last_name', 'Spam')]), OrderedDict([('first_name', 'Wonderful'), ('last_name', 'Spam')])]

您可以完全一样地访问密钥,OrderedDict 只是保持密钥插入顺序:

In [2]: import csv
   ...: with open("in.csv") as csvfile:
   ...:     reader = csv.DictReader(csvfile, delimiter=" ")
   ...:     for dct in reader:
   ...:         print(f"dct['first_name'] dct['last_name']")
   ...:         
   ...:     
Baked Beans
Lovely Spam
Wonderful Spam

py3.6 实际上也是如此,所以如果出于某种原因你真的想要一个 dict:

In [5]: import csv
   ...: with open("in.csv") as csvfile:
   ...:     reader = csv.DictReader(csvfile, delimiter=" ")
   ...:     for dct in map(dict, reader):
   ...:         print(dct)
   ...:         print(f"dct['first_name'] dct['last_name']")
   ...:         
   ...:     
'first_name': 'Baked', 'last_name': 'Beans'
Baked Beans
'first_name': 'Lovely', 'last_name': 'Spam'
Lovely Spam
'first_name': 'Wonderful', 'last_name': 'Spam'
Wonderful Spam

py3.6 中插入时的排序保留是一个实现细节,可能会发生变化,但如果我们有足够多的人使用它,它可能只需要保留 :)

【讨论】:

Python 3.6 不正确,应该使用print([dict(d) for d in reader]) @MattFletcher,它在 py3.6 中运行良好,什么不适合你?是因为你看到了OrderedDict's吗? 是的,因此无法正确迭代它。我不是 Python 大师,所以我可能会遗漏一些重要的东西,但我读到它们的工作方式在 py3.6 中已经改变——我一辈子都找不到 SO 线程...... @MattFletcher,我在答案中添加了更多内容,OrderDict 是,出于所有意图和目的,它只是一个字典,它只是维护插入顺序,因此对于您的 csv,您会看到列/键与它们在文件中出现的顺序相同。 明白了。那就怪我自己的愚蠢;)感谢您的澄清,我一直在用Dict vs OrderedDict撞我的头!【参考方案4】:

使用list():

print(list(reader))

演示:

>>> with open('names.csv') as csvfile:
...     reader = csv.DictReader(csvfile, delimiter=" ")
...     print(list(reader))
... 
['first_name': 'Baked', 'last_name': 'Beans', 'first_name': 'Lovely', 'last_name': 'Spam', 'first_name': 'Wonderful', 'last_name': 'Spam']

【讨论】:

如果csv文件有很多列怎么办?它将如何形成字典或列表 @HNSingh 列表中的字典会更长。在上面的示例中,仅有的列是 first_namelast_name

以上是关于将 csv.DictReader 对象转换为字典列表?的主要内容,如果未能解决你的问题,请参考以下文章

如何读取 2 列 csv 文件并创建字典?

从 csv 文件创建字典?

在 python 中使用 csv.DictReader 进行数据类型转换的最快方法

Python解析CSV中的多维字典

如何复制python DictReader对象?

如何仅用 reduce 和 map 每年总结一本字典?