【问题标题】:Python - CSV to JSON - nestedPython - CSV 到 JSON - 嵌套
【发布时间】:2019-11-21 00:11:03
【问题描述】:

我有这个 csv:

product_id, width, height
14866, 200, 200
14866, 300, 300

我正在使用 csv 导入和 json 来尝试创建一个 json 来发出 api 请求。

这就是我的python现在的样子:

import csv
import json


json_dict = {}
results = []
with open('sizes.csv',encoding='utf-8-sig') as f:
   for row in csv.DictReader(f,):
        results.append(
            {'id': int(row['product_id']),
             'product': 
             {'product_creative_size_attributes':[{'width':str(row['width']),'height': str(row['height'])}]}})

json_dict["sizes"] = results

output_json = print(json.dumps(json_dict,indent=4))

这会导致这个 json:

{
    "sizes": [
        {
            "id": 14866,
            "product": {
                "product_creative_size_attributes": [
                    {
                        "width": "200",
                        "height": "200"
                    }
                ]
            }
        },
        {
            "id": 14866,
            "product": {
                "gam_product_creative_size_attributes": [
                    {
                        "width": "300",
                        "height": "300"
                    }
                ]
            }
        }
    ]
}

我想要实现的 json 是将相同 product_id 的尺寸嵌套如下:

{
    "sizes": [
        {
            "id": 14866,
            "product": {
                "product_creative_size_attributes": [
                    {
                        "width": "200",
                        "height": "200"
                    },
                    {
                        "width": "300",
                        "height": "300"
                    }
                ]
            }
        }
    ]
}

【问题讨论】:

  • 您希望它们按product_id分组吗?
  • 考虑分两个阶段填充输出。首先识别唯一的product_ids,并为每个创建{'id': <product_id>, 'product': {'product_creative_size_attributes': []}}。然后循环遍历每个 csv 行,再次附加到特定产品的嵌套数组。
  • @Boris 是的,我希望它们按 product_id 分组 - 但我需要将“product_creative_size_attributes”嵌套在“product”下
  • @FraggaMuffin 我是一个超级 python 初学者 - 你能告诉我一个示例 python 来显示你的建议吗?
  • 请注意,有两个不同的值与"product" 相关联——哪一个应该“获胜”并最终出现在组合结果中?

标签: python json csv nested


【解决方案1】:

我将首先按产品 ID 和列表的collections.defaultdict 进行分组,然后组装您的最终字典并将其序列化为 JSON。

演示:

from csv import DictReader
from collections import defaultdict
from json import dumps

result = {}
products = defaultdict(list)

with open("sizes.csv") as f:

    # make sure headers don't have whitespace, since they are used as dict keys later
    header = [h.strip() for h in next(f).split(",")]

    for row in DictReader(f, fieldnames=header):
        products[int(row["product_id"])].append(
            {"width": int(row["width"].strip()), "height": int(row["height"].strip())}
        )

# transform your grouped products into your desired result
result["sizes"] = [
    {"id": k, "product": {"product_creative_size_attributes": v}}
    for k, v in products.items()
]

output_json = dumps(result, indent=4)

print(output_json)

输出:

{
    "sizes": [
        {
            "id": 14866,
            "product": {
                "product_creative_size_attributes": [
                    {
                        "width": 200,
                        "height": 200
                    },
                    {
                        "width": 300,
                        "height": 300
                    }
                ]
            }
        }
    ]
}

【讨论】:

  • collections.defaultdict 是否允许我在嵌套项目中创建嵌套?例如,如果我想要:“sizes”:[{“id”:14866,“product”:{“product_creative_size_attributes”:[{“width”:200,“height”:200,“companion_sizes”:[{“width” :100,“高度”:100},{“宽度”:300,“高度”:300}] }
【解决方案2】:
import csv
import json

k_product_id  = 0
k_width       = 1
k_height      = 2
json_dict     = {}
results       = []

with open('sizes.csv', encoding='utf-8-sig') as f:
  reader = csv.reader(f)
  # Avoid header
  next(reader, None)
  for row in reader:
    # Find index of existing product id
    existing_id = list(i for i,v in enumerate(results) if v['id'] == int(row[k_product_id]))

    # If there is no existing product id
    if not existing_id:
      results.append(\
                      {\
                        "id": int(row[k_product_id]),\
                        "product":\
                        {\
                          "product_creative_size_attributes":\
                            [\
                              {\
                                "width": int(row[k_width]),\
                                "height": int(row[k_height])\
                              }\
                            ]\
                        }\
                      }\
                    )
    # If there is existing product id
    else:
      results[existing_id[0]]['product']['product_creative_size_attributes']\
        .append(\
                  {\
                    "width": int(row[k_width]),\
                    "height": int(row[k_height])\
                  }\
               )

json_dict['sizes'] = results
output_json = json.dumps(json_dict, indent=4)

【讨论】:

    猜你喜欢
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 2020-07-06
    • 2018-08-29
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多