导入包含来自csv

时间:2015-05-10 21:04:45

标签: python list csv dictionary

我有一个包含列表作为值的字典(见下文),并希望将其保存到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
[

有人能帮助我或为我提供替代方案吗? 非常感谢提前!

4 个答案:

答案 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章解释了 用于数据序列化和交换的选项:jsonpicklecsv *在stdlib中。或者您可以转向第三方模块,如PyYAML,或将内容存储在数据库中等。如果您了解每个模块的优点和缺点,json在这种情况下是明显的答案,正如Jimmy C's answer所示。

*是的,您可以使用CSV文件行中逗号分隔值的列表,只要您使用不同的分隔符,或允许csv引用内容。有关这样做的简单方法,请参阅alexis's answer,或者通过递归使用csv.writercsv.reader来搜索ActiveState配方,以获得存储2级列表的奇特方式。但通常,你不想这样做; JSON的优点是可以任意递归,而不仅仅是2级递归,而且使用起来更加简单。

答案 3 :(得分:0)

我会用泡菜

{{1}}