【问题标题】:Python save arbitrarily nested list to CSVPython将任意嵌套列表保存到CSV
【发布时间】:2015-09-30 10:03:36
【问题描述】:

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

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...

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

【问题讨论】:

  • 请向我们展示您的尝试。如果你还没有,一旦你从一个方向开始,有人可以帮助你想出一个准确的解决方案。事实上,这应该不是那么难 - 以写入模式打开一个 csv 文件,然后在循环中开始写入文件。
  • 一个更优雅的解决方案比什么?显示您尝试过的内容...
  • 我认为最简单的是flatten each item first然后保存到csv。

标签: python list csv


【解决方案1】:

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

CSV 是一种扁平的表格存储格式。 “任意嵌套列表”的分层性质根本无法很好地匹配或适合表格结构。

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

演示:

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

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

两者都会发射:

1
Two,Three
4.0

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

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

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

import json

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

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

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

但如果你真的想要 CSV 风格的文本:

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

【讨论】:

  • 我知道这两种形式是否不兼容。然而,就我的目的而言,嵌套列表的原始结构并不重要(实际上是任意的)。
  • 那么扁平化方法就可以了。这比使用现有的 I/O 模块(如 json)更直接一些,而且它仍然不是格式良好的 CSV,但可以避免大多数扁平化问题。
  • 好的,所以我添加了 list-flatten-to-CSV 代码。这并不理想,但它会按照您的要求进行。
  • 就是这样!我一直试图将类似的东西放在一起,但没有效果
  • 请注意,这里存在一些持续的复杂性。如果您的字符串中有 Unicode 字符怎么办?这在 Python 3 中可以处理,但在 Python 2 中需要更多代码。另外,如果字符串中有逗号或嵌入的引号怎么办?在完整的生产就绪版本中需要有更复杂的引用和转义逻辑。但作为概念证明,它的效果非常好。
猜你喜欢
  • 1970-01-01
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
  • 2016-01-05
  • 2019-01-28
  • 1970-01-01
相关资源
最近更新 更多