将 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_name
和 last_name
。以上是关于将 csv.DictReader 对象转换为字典列表?的主要内容,如果未能解决你的问题,请参考以下文章