在特定位置将 Python 字典添加到另一个字典

Adding a Python dict to another dict, in a certain location

我有一个 .json 文件,其中包含如下所示的对象:

[
  {
    "a": "0.038",
    "b": "1",
    "c": "0"
  },
  {
    "a": "0.040",
    "b": "1",
    "c": "0"
  },
  ...
]

我有一个 .csv 文件,如下所示:

d   e   f
0.00    0.00    0.00
0.02    -0.08   -0.08
0.04    -0.32   -0.32
...

我想修改 .json 文件以从 .csv 文件中添加新的 key/value 对,但我不想只在文件,而是 .csv 中的一行被添加到每个元素的末尾。所以新的 .json 看起来像这样:

[
  {
    "a": "0.038",
    "b": "1",
    "c": "0",
    "d": "0.00",
    "e": "0.00",
    "f": "0.00"
  },
  {
    "a": "0.040",
    "b": "1",
    "c": "0",
    "d": "0.02",
    "e": "-0.08",
    "f": "-0.08""
  },
  ...
]

我尝试了不同的方法(比如使用 append() 或 update()),但他们要么将 .csv 数据添加到 .json 文件的完整末尾,要么尝试将整个 .csv 添加到文件中。 csv 数据到 .json 中第一个元素的末尾。在我看来,我需要做的是,从 json 对象创建一个字典,将 csv 数据也加载到字典中,遍历每个 json 元素,然后从 csv 添加一行数据,创建一个新的 json 对象。但是我没有得到我想要的输出,或者我 运行 遇到无法附加到字典的问题。这是我现有的代码:

import csv
import json

def csv_to_json(csvFilePath, jsonFilePath):

    with open("existing.json") as json_file:
        data = json.load(json_file)
    json_file.close() # Close the JSON file
    
    #read csv file
    with open(csvFilePath, encoding='utf-8') as csvf:
        #load csv file data using csv library's dictionary reader
        csvReader = csv.DictReader(csvf)
        
        for item in data:
            #convert each csv row into python dict
            for row in csvReader:
                #add this python dict to json array
                item.update(row)
                     
    #convert python jsonArray to JSON string and write to file
    with open(jsonFilePath, 'w', encoding='utf-8') as jsonf:
        jsonString = json.dumps(data, indent = 4)
        jsonf.write(jsonString)
        
#decide the 2 file paths according to your file system
csvFilePath = r'C:\Users\Downloads\filename.csv'
jsonFilePath = r'C:\Users\Desktop\filename.json'

csv_to_json(csvFilePath, jsonFilePath)

你的问题是你有嵌套循环。这会产生几个问题:

for item in data:
    #convert each csv row into python dict
    for row in csvReader:
        #add this python dict to json array
        item.update(row)
  1. csvReader = csv.DictReader(csvf) 使 csvReader 成为迭代器。一旦您在 for item in data 的第一次迭代结束时阅读了 csvReader 的所有行,该迭代器就会耗尽并且不会产生更多的行。因此,对于 data 中的后续 item,您将永远不会在 csvReader 中有任何行。您可以通过执行 csvReader = list(csv.DictReader(...)) 来解决此问题,这会将所有行读入一个列表,您可以在该列表上迭代任意次数。
  2. 一旦你解决了这个问题。您将 data 中的 每个 item 更新为 csvReader 所有行 。这不是您想要的,因为您只希望第 iitem 更新为第 i 行。

要解决此问题,您需要 zip() 两个迭代器,以便同时迭代 datacsvReader

for item, row in zip(data, csvReader):
    item.update(row)

请注意,由于在这种情况下您没有多次迭代 csvReader,因此它不需要是一个列表并且您的原始定义 csvReader = csv.DictReader(csvf) 就足够了(您可能需要 csvReader = csv.DictReader(csvf, delimiter="\t")指定分隔符,默认为逗号)

现在你有 data =

[{'a': '0.038', 'b': '1', 'c': '0', 'd': '0.00', 'e': '0.00', 'f': '0.00'},
 {'a': '0.040', 'b': '1', 'c': '0', 'd': '0.02', 'e': '-0.08', 'f': '-0.08'}]

使用zip将两个列表压缩在一起并合并字典:

>>> json_data = [
...   {
...     "a": "0.038",
...     "b": "1",
...     "c": "0"
...   },
...   {
...     "a": "0.040",
...     "b": "1",
...     "c": "0"
...   },
... ]
>>>
>>> csv_data = [
...     {
...         "d": "0.00",
...         "e": "0.00",
...         "f": "0.00"
...     },
...     {
...         "d": "0.02",
...         "e": "-0.08",
...         "f": "-0.08"
...     }
... ]
>>> from pprint import pprint
>>> pprint([j | c for j, c in zip(json_data, csv_data)])
[{'a': '0.038', 'b': '1', 'c': '0', 'd': '0.00', 'e': '0.00', 'f': '0.00'},
 {'a': '0.040', 'b': '1', 'c': '0', 'd': '0.02', 'e': '-0.08', 'f': '-0.08'}]

在单个表达式中合并 2 个字典 here。 如果两个字典列表的长度相同:

list1 = [
  {
    "a": "0.038",
    "b": "1",
    "c": "0"
  },
  {
    "a": "0.040",
    "b": "1",
    "c": "0"
  }
]
list2 = [
  {
    "d": "0.00",
    "e": "0.00",
    "f": "0.00"
  },
  {
    "d": "0.02",
    "e": "-0.08",
    "f": "-0.08"
  }]

然后遍历任何列表的长度:

>>> result = [{**list1[i], **list2[i]} for i in range(len(list1))]
>>> result
[{'a': '0.038', 'b': '1', 'c': '0', 'd': '0.00', 'e': '0.00', 'f': '0.00'}, {'a': '0.040', 'b': '1', 'c': '0', 'd': '0.02', 'e': '-0.08', 'f': '-0.08'}]