我正在尝试遍历一个 JSON 对象,我试图在其中构建一个简单的规则:
如果 dict item 有一个名为
'breakup'
的键,则迭代该项目值中的每个项目,直到 'breakup'
中不再有值为止,并返回一个包含两个项目 'name'
和 'amount'
的字典,其中然后将被附加到包含所有费用的字典列表中。
例如:
[{'name': 'Brokerage', 'amount': 0.0}, {'name': 'Exchange Transaction Charges', 'amount': 0.3864}, {'name': 'Stamp Duty', 'amount': 1.8}, {'name': 'Regulatory Fees', 'amount': 0.012},{'name': 'Security Transaction Tax', 'amount': 12.0}, {'name': 'GST', 'amount': 0.071756}]
起始数据示例:
my_dict = {'total_charges': 14.270156, 'trade_value': 12000, 'breakup': [{'name': 'Brokerage', 'amount': 0.0, 'msg': '', 'breakup': []}, {'name': 'External Charges', 'amount': 2.1984, 'msg': '', 'breakup': [{'name': 'Exchange Transaction Charges', 'amount': 0.3864, 'msg': '', 'breakup': []}, {'name': 'Stamp Duty', 'amount': 1.8, 'msg': '', 'breakup': []}, {'name': 'Regulatory Fees', 'amount': 0.012, 'msg': '', 'breakup': []}]}, {'name': 'Taxes', 'amount': 12.071756, 'msg': '', 'breakup': [{'name': 'Security Transaction Tax', 'amount': 12.0, 'msg': '', 'breakup': []}, {'name': 'GST', 'amount': 0.071756, 'msg': '', 'breakup': []}]}]}
我知道这需要是一个递归函数。到目前为止我想到的是:
def my_filtering_function(pair):
filter_keys = ['name', 'amount']
key, value = pair
if key in filter_keys:
return True # keep pair in the filtered dictionary
else:
return False # filter pair out of the dictionary
def json_traverse(json_object):
charges_list = []
if "breakup" in json_object and len(json_object['breakup']) == 0:
charges_list.append(dict(filter(my_filtering_function, a.items())))
else:
breakup = json_object['breakup']
for item in breakup:
json_traverse(item)
我尝试了多种其他变体,但似乎都不起作用。任何建议都会很有帮助。
主要问题是您在函数内部定义了
charges_list = []
,因此它是局部变量,并且您无法在函数外部访问它。它还在每次递归中分配空列表,以便删除以前的值。您必须在函数外部声明它。
其他问题:
a.items()
但您不创建 a
- 看来您需要 json_object.items()
"breakup" in json_object
中检查 if
- 因此当数据中没有 else
时,"breakup"
可以运行。您应该首先仅检查 "breakup" in json_object
,然后检查 if len(json_object['breakup']) == 0: ... else: ...
(或更短的 if not json_object['breakup']: ... else: ...
)def json_traverse(json_object):
if "breakup" in json_object:
if not json_object['breakup']:
charges_list.append(dict(filter(my_filtering_function, json_object.items())))
else:
for item in json_object['breakup']:
json_traverse(item)
其他想法:
代码
key in filter_keys
给出 True
或 False
- 这样你就可以在没有 return key in filter_keys
的情况下执行
if/else
您甚至可以将函数中的代码减少到一行
def my_filtering_function(pair):
return pair[0] in ['name', 'amount']
或者甚至运行它作为
lambda
filter(lambda pair:pair[0] in ['name', 'amount'], json_object.items())