【问题标题】:python - Nested list in dict to csv filespython - dict中的嵌套列表到csv文件
【发布时间】:2015-03-16 21:25:32
【问题描述】:

我尝试从两个 json 文件创建一个 csv 文件。

第一个 json 文件:

{ "attributes": [
        {
            "code": "ean",
            "description": "the ean",
            "example": null,
            "hierarchy_code": null,
            "label": "ean",
            "required": true,
            "type": "TEXT",
            "type_parameter": null,
            "values": null,
            "values_list": "some value"
        },
        ...

第二个json文件:

{
    "code": "the code",
    "label": "shoes",
    "values": [
        {
            "code": "COL_100",
            "label": "white"
        },
        {
            "code": "COL_101",
            "label": "blue"
        },
        ...

我需要从第一个 json 中的键“values_list”中获取值。 使用该键,我可以从第二个 json 中获取一个列表(它返回随机数量的值)并获取“标签”键值。

我的发现是制作两个这样的循环:

for att in first_json['attributes']:
    csv_dict[att['values_list']] = []
    for val in second_json['values']:
        csv_dict[att['values_list']].append(val['label'])

这会创建一个像这样的字典:

{'label1': [val1, val2, val3], 
'label2': [otherval1, otherval2, ...], 
...}

我的问题:

使用我的“csv_dict”字典,我如何创建一个结构如下的 csv:

label1 | label2    | ... | labeln
val1   | otherval1 | ... | valn
val2   | otherval2 | ... |
val3   | ...       | ... |

我的实际字典似乎不适合通常使用的 csv.Dictwriter() 方法。

https://docs.python.org/2/library/csv.html#csv.DictWriter

我尝试像这样使用 zip 功能:

for elem in zip(*labels.values()):
    data.append(";".join([otherelm for otherelem in elem]))

希望手动创建一个 csv 文件,但我的尝试失败了。

感谢您的帮助。

【问题讨论】:

  • 您能否更具体地说明您的最终结果应该是什么样子?使用dict[att['values_list']],您将多次覆盖同一个键(att['values_list'])的值,这是故意的吗?并且不要使用 dict 作为变量名,因为它是 Python 中字典类的名称。
  • 目前还不清楚“像这样的 csv:label1 label2 val1 otherval1 val2 otherval2 val3”是什么意思。请提供更多信息。
  • 我更新了我的解释。我希望它会更清楚。

标签: python json csv dictionary


【解决方案1】:

好的,我看到你更新了你的问题,所以它给出了一个完全不同的含义。试试这个:

import csv

labels =  {
    'label1': ["val1", "val2", "val3"],
    'label2': ["otherval1", "otherval2", "otherval3"]
}

keys = [k for k in labels]

with open('file.csv', 'wb') as f
    w = csv.DictWriter(f, keys)
    w.writeheader()
    for group in zip(*labels.values()):
        temp = {}
        for i in group:
            temp[keys[group.index(i)]] = i
        w.writerow(temp)

试试这个,它应该适用于任何大小的 json 对象

【讨论】:

  • 这是个好主意,和我想要的一样,但是带有“*labels.value()”的循环返回一个空列表。
【解决方案2】:

从您的csv_dict 开始,您可以执行类似的操作

import csv
import itertools

csv_dict = {'label1': ['val1', 'val2', 'val3'],
            'label2': ['otherval1', 'otherval2'],
            'label3': ['yetanotherval1']}
keys = csv_dict.keys()
csvrows = itertools.izip_longest(*[csv_dict[k] for k in keys], fillvalue='dummy')

with open('out.csv', 'w') as csvfile:
    csvwriter = csv.writer(csvfile, delimiter=';',
                            quotechar='\\', quoting=csv.QUOTE_MINIMAL)
    csvwriter.writerow(keys)
    for row in csvrows:
        csvwriter.writerow(row)

结果out.csv

label1;label2;label3
val1;otherval1;yetanotherval1
val2;otherval2;dummy
val3;dummy;dummy

附注如下:

  • 当你zipping 字典的值时,你应该指定 键的顺序
  • 如果列的长度不同(在您的示例中,有val1val3,但只有两个othervals),您想做什么?也许像padding all lists to fit the longest list 这样的东西?

【讨论】:

  • 在我的解释中,我写了一些“...”来模拟无限数量的值。事实上,嵌套列表的长度可能不同。
  • 查看更新的答案。而且我认为您实际上并不是指“无限”,而是“未知”:)
  • "当你压缩字典的值时,你应该指定键的顺序" 我无法预测我的字典会有多少键,所以我想使用可以提供的通配符动态分配。但我没有使用我的代码。
  • 请查看更新后的答案。 “没有为我工作”没有帮助,总是说明你做了什么,你得到了什么以及你期望什么!
  • 我使用的数据,包含unicode字符串,所以前面的代码返回一个空列表。但是现在有了这个版本,它就可以工作了。我已经使用 csv 库管理了 unicode 转换。感谢您的帮助。
猜你喜欢
  • 2015-09-20
  • 2012-10-09
  • 1970-01-01
  • 2018-09-07
  • 1970-01-01
  • 2021-04-24
  • 2023-03-27
  • 1970-01-01
  • 2011-01-25
相关资源
最近更新 更多