我有一个包含列表作为值的字典(见下文),并希望将其保存到csv。到目前为止保存工作正常,但是当我把它读回到我的程序中时,我得到了下面的结果,其中两个列表[1,2,3]和[4,5,6]不再列出了,但是字符串(" [1,2,3]"和" [4,5,6]")。
如何从csv列表中加载列表而不是字符串?这样我就可以再次访问列表中的元素而不是单个字符(见下文)。
nodes = []
test_list = [{'Key' : 'key1', 'List' : [1,2,3]},
{'Key' : 'key2', 'List' : [4,5,6]}]
with open('list.csv', 'wb') as f:
writer = csv.DictWriter(f, test_list[0].keys(), delimiter=';')
writer.writeheader()
for entry in test_list:
writer.writerow(entry)
with open('list.csv') as f:
dataset = csv.DictReader(f, delimiter=';')
for row in dataset:
nodes.append(row)
for elem in nodes:
print elem
结果:
{'Key': 'key1', 'List': '[1, 2, 3]'}
{'Key': 'key2', 'List': '[4, 5, 6]'}
问题:
所以现在列表是字符串,我无法访问列表中的数字,因为它现在是一个字符列表。
>> print nodes[0]['List'][0] # print first number from list in first dictionary
[
有人能帮助我或为我提供替代方案吗? 非常感谢提前!
答案 0 :(得分:3)
CSV并不是以这种方式存储嵌套列表。您可以使用eval
,但这是一个相当安全的麻烦,因为它允许人们在您的计算机上运行代码,例如,如果您有人将他们的文件上传到您的服务器。相反,我建议您将字典存储为JSON对象。这将解决许多可能在以后出现的特殊情况。
import json
test_list = [{'Key' : 'key1', 'List' : [1,2,3]},
{'Key' : 'key2', 'List' : [4,5,6]}]
with open('/tmp/test_list.json', 'w') as f:
json.dump(test_list, f)
然后加载它:
with open('/tmp/test_list.json') as f:
test_list = json.load(f)
答案 1 :(得分:1)
我同意@Jimmy:CSV不太适合存储列表。正如他所说,切换到JSON是最好的现成解决方案。
如果由于某种原因您不能或不想切换到JSON,您应该自己打包列表,这样它们就可以作为CSV中的单个单元格进行存储和检索,并自行处理解压缩。 IF 所有列表数据都是整数列表,您可以打包并解压缩它们:
...
for entry in test_list:
entry["List"] = ",".join( str(n) for n in entry["List"] )
writer.writerow(entry)
# Reading in
for row in csv.DictReader(f, delimiter=';'):
row["List"] = [ int(n) for n in row["List"].split(",") ]
nodes.append(row)
因为您使用了“;”作为CSV中的字段分隔符,我使用“,”作为列表分隔符。如果您的作者报价正确,则没有必要这样做,但它更清晰。
答案 2 :(得分:1)
这里的根本问题是CSV只存储字符串。因此,将list
放入CSV单元格本身意味着自动对该列表进行字符串化,然后强制您再次将其解析出来。
如果列表确实只是一个整数列表,literal_eval
将起作用。 (并且列表应该只是一个整数列表,但事实上实际上是不同的 - 无论是因为错误,还是因为恶意用户 - 它会给你一个很好的错误,而不是默默地做一些危险的事情,或者提出一些毫无意义的令人困惑的异常。)但这不是一个好主意。 Python的repr
并不是数据序列化或交换格式;它旨在成为一种帮助人类程序员理解其数据的格式。
本教程的Input/Output章解释了 用于数据序列化和交换的选项:json
,pickle
和csv
*在stdlib中。或者您可以转向第三方模块,如PyYAML
,或将内容存储在数据库中等。如果您了解每个模块的优点和缺点,json
在这种情况下是明显的答案,正如Jimmy C's answer所示。
*是的,您可以使用CSV文件行中逗号分隔值的列表,只要您使用不同的分隔符,或允许csv
引用内容。有关这样做的简单方法,请参阅alexis's answer,或者通过递归使用csv.writer
和csv.reader
来搜索ActiveState配方,以获得存储2级列表的奇特方式。但通常,你不想这样做; JSON的优点是可以任意递归,而不仅仅是2级递归,而且使用起来更加简单。
答案 3 :(得分:0)
我会用泡菜
{{1}}