【问题标题】:Writing a CSV horizontally水平写入 CSV
【发布时间】:2013-07-31 18:37:28
【问题描述】:

假设我们正在从具有多个键值对的某个来源读取数据。我们以下面的列表为例:

[{'key0': 'key0_value0', 'key1': 'key1_value0'},
 {'key0': 'key0_value1', 'key1': 'key1_value1'}]

从该列表中读取第一项应生成如下所示的 CSV:

key_header | 0
---------------------------
key0       | key0_value_0
key1       | key1_value_0

现在阅读第二项应该会得到以下结果:

key_header | 0            | 1
----------------------------------------
key0       | key0_value_0 | key0_value_1
key1       | key1_value_0 | key1_value_1

这会水平进行,直到。写这个的算法超出了我的范围,我不确定the csv module 是否有效,因为它似乎假设数据将一次写入一行。

【问题讨论】:

  • 使用生成器将它们按顺序排列,然后使用 zip()。

标签: python csv


【解决方案1】:

您必须首先收集所有“列”,然后写入。您可以通过将所有内容转换为列表列表,然后使用zip(*columns) 将列列表转换为行列表来实现:

columns = [['key_header'] + sorted(inputlist[0].keys())]  # first column

for i, entry in enumerate(inputlist):
    columns.append([i] + [entry[k] for k in columns[0][1:]])

with open(outputfilename, 'wb') as output:
    writer = csv.writer(output)
    writer.writerows(zip(*columns))

显示行输出的演示:

>>> from pprint import pprint
>>> inputlist = [{'key0': 'key0_value0', 'key1': 'key1_value0'},
...  {'key0': 'key0_value1', 'key1': 'key1_value1'}]
>>> columns = [['key_header'] + sorted(inputlist[0].keys())]  # first column
>>> for i, entry in enumerate(inputlist):
...     columns.append([i] + [entry[k] for k in columns[0][1:]])
... 
>>> pprint(zip(*columns))
[('key_header', 0, 1),
 ('key0', 'key0_value0', 'key0_value1'),
 ('key1', 'key1_value0', 'key1_value1')]

【讨论】:

    【解决方案2】:

    没有办法逐步写入列,因为这不是文本文件(CSV 文件是其子集)的工作方式。您不能附加到文件中间的行/行;您所能做的就是在末尾添加新行。

    但是,我不确定您为什么需要这样做。只需转置内存中的列表,然后逐行写入。

    例如:

    values = [{'key0': 'key0_value0', 'key1': 'key1_value0'},
              {'key0': 'key0_value1', 'key1': 'key1_value1'}]
    transposed = zip(*(x.items() for x in values))
    grouped = ([pairs[0][0]] + [pair[1] for pair in pairs] for pairs in transposed)
    writer.writerows(grouped)
    

    仅仅转置items 是不够的,因为您最终会得到每个值的key0 副本,而不仅仅是一个副本。这就是grouped 的用途。

    【讨论】:

    • 这不是假设所有字典的.items() 调用都会以相同的顺序返回键吗?根据他们的插入历史是否相同可能有点脆弱?
    猜你喜欢
    • 2015-11-21
    • 2014-11-18
    • 1970-01-01
    • 2018-06-21
    • 1970-01-01
    • 2020-01-18
    • 2020-03-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多