在特定位置将 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)
csvReader = csv.DictReader(csvf)
使 csvReader
成为迭代器。一旦您在 for item in data
的第一次迭代结束时阅读了 csvReader
的所有行,该迭代器就会耗尽并且不会产生更多的行。因此,对于 data
中的后续 item
,您将永远不会在 csvReader
中有任何行。您可以通过执行 csvReader = list(csv.DictReader(...))
来解决此问题,这会将所有行读入一个列表,您可以在该列表上迭代任意次数。
- 一旦你解决了这个问题。您将
data
中的 每个 item
更新为 csvReader
的 所有行 。这不是您想要的,因为您只希望第 i
行 item
更新为第 i
行。
要解决此问题,您需要 zip()
两个迭代器,以便同时迭代 data
和 csvReader
:
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'}]
我有一个 .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)
csvReader = csv.DictReader(csvf)
使csvReader
成为迭代器。一旦您在for item in data
的第一次迭代结束时阅读了csvReader
的所有行,该迭代器就会耗尽并且不会产生更多的行。因此,对于data
中的后续item
,您将永远不会在csvReader
中有任何行。您可以通过执行csvReader = list(csv.DictReader(...))
来解决此问题,这会将所有行读入一个列表,您可以在该列表上迭代任意次数。- 一旦你解决了这个问题。您将
data
中的 每个item
更新为csvReader
的 所有行 。这不是您想要的,因为您只希望第i
行item
更新为第i
行。
要解决此问题,您需要 zip()
两个迭代器,以便同时迭代 data
和 csvReader
:
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'}]