将python十进制转换为深度嵌套且不可预测的列表中的字符串 [英] Convert python decimal to string in deeply nested and unpredictable list
问题描述
我试图遍历深层嵌套/混合列表中的每个值,并将任何Decimal实例转换为字符串,以便将其存储在mongo中.
I am trying to loop through every value in a deeply nested/mixed list and convert any Decimal instances to string so that I can store them in mongo.
我的递归尝试达到了最大深度.我想以迭代或高性能的方式解决这个问题.
My attempt at recursion reached the max depth. I would like to solve this iteratively or in a performant manner.
这似乎不起作用,但这是我的最新尝试:
This doesn't seem to work but is my latest attempt:
def convert_decimals(root_obj):
objs_to_convert = [root_obj]
while objs_to_convert:
obj = objs_to_convert.pop(0)
for k, v in enumerate(obj):
if len(v):
objs_to_convert.append(v)
elif isinstance(v, Decimal):
obj[k] = str(v)
样本输入:
[
{
'Payments': {
'Payment': Decimal('495.64'),
'IsCapped': True,
'OtherFees': Decimal('0'),
'CapCostTotal': Decimal('27900'),
'Name': 'TestData',
'Program': {
'ProgramName': u'AST',
'Description': None
},
'Rate': Decimal('0.0254'),
'APR': Decimal('2.54'),
'AppliedIds': [
],
'Tax': Decimal('0')
}
}
]
转换后,十进制实例应为字符串
After conversion, the decimal instances should be strings
推荐答案
要在json.dump()
期间使用default
参数转换Decimal
:
To convert Decimal
during json.dump()
using default
parameter:
import json
import sys
from decimal import Decimal
def default(obj):
if isinstance(obj, Decimal):
return str(obj)
else:
raise TypeError(obj)
# convert during dump
json.dump(data, sys.stdout, indent=2, default=default)
要就地修改data
:
import json
import sys
from collections import MutableMapping, MutableSequence
from decimal import Decimal
def convert_decimal(json_data):
stack = [json_data]
while stack:
json_data = stack.pop()
if isinstance(json_data, MutableMapping): # json object
it = json_data.items()
elif isinstance(json_data, MutableSequence): # json array
it = enumerate(json_data)
else: # scalar data
continue
for k, v in it:
if isinstance(v, Decimal):
json_data[k] = str(v)
else:
stack.append(v)
# convert inplace
convert_decimal(data)
json.dump(data, sys.stdout, indent=2)
两个脚本产生相同的输出:
Both scripts produce the same output:
[
{
"Payments": {
"OtherFees": "0",
"APR": "2.54",
"Rate": "0.0254",
"IsCapped": true,
"Name": "TestData",
"Program": {
"Description": null,
"ProgramName": "AST"
},
"AppliedIds": [],
"CapCostTotal": "27900",
"Tax": "0",
"Payment": "495.64"
}
}
]
如果使用通用get_items()
函数,则可以简化convert_decimal()
:
def convert_decimal(json_data):
stack = [json_data]
while stack:
json_data = stack.pop()
for k, v in get_items(json_data):
if isinstance(v, Decimal):
json_data[k] = str(v)
else:
stack.append(v)
这篇关于将python十进制转换为深度嵌套且不可预测的列表中的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!