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

Python save arbitrarily nested list to CSV

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

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

我希望列表中的每一项都写入到csv文件中的一行。因此,考虑到上述数据,文件应该如下所示:

1
2
3
4
5
1.0
One
1,Two
1,Two,Three,4.5
One,2,3.4,Five,6

关于如何将列表写入文件有很多资源,但是我没有看到任何一个独立于列表嵌套性的列表。我相信我能想出一些涉及许多循环的东西,等等,但是有人有更优雅的解决方案吗?

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

1
2
3
4
5
6
7
8
9
10
string = ''
for i in data:
    line = str(i).replace("[","")
    line = line.replace("]","")
    line = line.replace("'","")
    line = line.replace("","")
    string+=line + '
'


# write string to file...

这只会让人觉得有些笨拙,而且它可能有害,因为它假定字符串不包含方括号、引号或空格。我正在寻找更好的解决方案!


你所要求的或多或少是不可能的。

csv是一种扁平的表格存储格式。"任意嵌套列表"的层次结构性质与表格结构不匹配或不适合。

您一定可以展平嵌套列表,这样嵌套列表的每个第一级元素都将显示在输出文件的单行上。但严格来说,这不是csv。一些csv阅读器可能会正确读取数据,但其他阅读器则不会。而且,一旦像您的示例中一样被展平,就不能通过读取文件来重建原始列表。

演示:

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

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

两者都会发出:

1
2
3
1
Two,Three
4.0

因此,在读取该文件时,阅读器/解析器将不知道返回原始列表中的哪一个——第一个、两级列表,或者第二个、三级列表。(我可以任意地使反例复杂难看。)

一般来说,嵌套/层次结构和平面/表格结构并不容易或完全兼容。

如果您想要一个任意嵌套列表的简单存储格式,可以考虑JSON或YAML。它们为嵌套数据提供了简单、高质量的存储。例如。:

1
2
3
4
5
import json

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

将数据写入文件。要重新阅读:

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

但如果你真的想要csv-ish文本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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"
"
.join(lines)

print list2csv(data)

产量:

1
2
3
4
5
1.0
One
1,Two
1,Two,Three,4.5
One,2,3.4,Five,6