Python将任意嵌套列表保存为CSV

时间:2015-09-30 00:44:39

标签: python list csv

我有一个由字符串,整数和浮点数组成的列表,以及字符串,整数和浮点数的嵌套列表。这是一个例子

data = [
        1.0,
        'One',
        [1, 'Two'],
        [1, 'Two', ['Three', 4.5]],
        ['One', 2, [3.4, ['Five', 6]]]
    ]

我希望列表中的每个项目都写入CSV文件中的一行。因此,鉴于上述数据,文件将如下所示:

1.0
One
1,Two
1,Two,Three,4.5
One,2,3.4,Five,6

有很多关于如何将列表写入文件的资源,但我没有看到任何这样做独立列表的嵌套性。我敢肯定我能想出一些涉及很多循环等的东西,但有没有人有更优雅的解决方案呢?

编辑:我想出的最好的事情是将列表中的每个项目转换为字符串,然后删除多余的字符(“[”,“]”等)。然后附加项目字符串,并将结果写入文件:

string = ''
for i in data:
    line = str(i).replace("[","")
    line = line.replace("]","")
    line = line.replace("'","")
    line = line.replace(" ","")
    string+=line + '\n'

# write string to file...

这只是感觉很麻烦,并且它可能有害,因为它假设字符串不包含括号,引号或空格。我正在寻找更好的解决方案!

1 个答案:

答案 0 :(得分:4)

你问的是或多或少是不可能的。

CSV是一种扁平的表格存储格式。 "任意嵌套列表的等级性质"只是不匹配或很好地适应表格结构。

您绝对可以展平嵌套列表,以便嵌套列表的每个第一级元素都显示在输出文件的单行上。但严格来说,这不是CSV。某些CSV阅读器可能正确读取数据,但其他人不会。而且,如果在示例中展平,则无法通过读取文件重建原始列表。

演示:

[1, ["Two", "Three"], 4.0]

[1, ["Two", ["Three"]], 4.0]

两者都会发出:

1
Two,Three
4.0

因此,在阅读该文件时,读者/解析器不知道要返回哪个原始列表 - 第一个,两个级别的列表,或者第二个三级列表。 (我可以将这个反例任意复杂和丑陋。)

通常,嵌套/分层结构和平面/表格结构不容易或完全兼容。

如果您想为任意嵌套列表提供简单的存储格式,请考虑JSONYAML。它们为嵌套数据提供简单,高质量的存储。 E.g:

import json

outpath = 'out.json'
with open(outpath, "w") as f:
    f.write(json.dumps(data))

会将您的数据写入文件。请阅读:

data = json.load(open(out path))

但如果你真的想要CSV-ish文字:

def flatten(l):
    """
    Flatten a nested list.
    """
    for i in l:
        if isinstance(i, (list, tuple)):
            for j in flatten(i):
                yield j
        else:
            yield i

def list2csv(l):
    """
    Return CSV-ish text for a nested list.
    """
    lines = []
    for row in l:
        if isinstance(row, (list, tuple)):
            lines.append(",".join(str(i) for i in flatten(row)))
        else:
            lines.append(str(row))
    return "\n".join(lines)

print list2csv(data)

收率:

1.0
One
1,Two
1,Two,Three,4.5
One,2,3.4,Five,6