python - Python:在深度嵌套的字典或数组中转换类型
问题描述
我编写了以下帮助函数来将 ObjectIds(bson 类型)转换为字符串。该函数应该适用于深度嵌套的字典、数组和两者的组合。
当前功能如下:
from datetime import datetime
from bson import ObjectId
def clean_dict_helper(d):
if not d:
return None
if isinstance(d, list): # For those db functions which return list
if len(d) == 0:
return []
return [clean_dict_helper(x) for x in d]
for k, v in d.items():
if isinstance(v, dict):
v = clean_dict_helper(v)
d.update({k: v})
else:
if isinstance(v, ObjectId):
v = str(v)
elif isinstance(v, datetime):
v = str(v)
d.update({k: v})
return d
test_case = {'id': bson.ObjectId("5e126ddf276ab18820e00ddf"), 'arr': [{'value': 4, 'id': bson.ObjectId("5e126ddf276ab18820e00ddf")}]}
result = clean_dict_helper(test_case)
print(result)
>>> {'arr': [{'id': ObjectId('5e126ddf276ab18820e00ddf'), 'value': 4}], 'id': '5e126ddf276ab18820e00ddf'}
但是,对于对象内部的数组内部的对象,它似乎失败了。我想知道是否有更好的方法来遍历嵌套的可迭代对象并转换类型?
解决方案
我认为如果将转换放在开头,允许递归调用传递ObjectId
并直接使用函数返回转换后的字符串,而不是尝试在函数的循环内进行转换,这将更容易推理。然后你可以将值传递给递归并取回字符串。
就像是:
from datetime import datetime
def clean_dict_helper(d):
if isinstance(d, ObjectId) or isinstance(d, datetime):
return str(d)
if isinstance(d, list): # For those db functions which return list
return [clean_dict_helper(x) for x in d]
if isinstance(d, dict):
for k, v in d.items():
d.update({k: clean_dict_helper(v)})
# return anything else, like a string or number
return d
来电:
clean_dict_helper({
1: {
1: ObjectId('5e0e83a6d0fbe7238c960ea0'),
2: [ObjectId('5e0e83a6d0fbe7238c960ea0'), ObjectId('5e0e83a6d0fbe7238c960ea0')],
3: datetime(2020, 1, 1),
4: [{1: ObjectId('5e0e83a6d0fbe7238c960ea0')}],
5: 'test'
},
2: [ObjectId('5e0e83a6d0fbe7238c960ea0'), ObjectId('5e0e83a6d0fbe7238c960ea0')]
})
然后将返回:
{1: {1: '5e0e83a6d0fbe7238c960ea0',
2: ['5e0e83a6d0fbe7238c960ea0', '5e0e83a6d0fbe7238c960ea0'],
3: '2020-01-01 00:00:00',
4: [{1: '5e0e83a6d0fbe7238c960ea0'}],
5: 'test'},
2: ['5e0e83a6d0fbe7238c960ea0', '5e0e83a6d0fbe7238c960ea0']}
此外,由于您正在创建一个带有理解的新列表,因此返回一个新的 dict 而不是使用以下内容改变传入的值可能是有意义的:
if isinstance(d, dict):
return {k:clean_dict_helper(v) for k, v in d.items() }
推荐阅读
- python - 解析字典以具有一对一的键值映射
- java - 从 ItemTouchHelper 取消 pendingIntent
- python - 如何修复“UnboundLocalError:分配前引用的局部变量'user_score'”?
- c++ - 如何在共享库路径而不是 C++ Linux/Windows 中的执行路径中搜索配置文件?
- python - 我正在尝试在 Python 中计算全年每一天的(最大值、最小值、平均值)温度的平均值和标准偏差
- php - 防止 PHP 移除 XML 标签
- javascript - window.Vue.use 不是函数
- bash - 来自外部 ifle 的 shell 递减变量
- logistic-regression - 如何使用**人工蜂群**算法训练**逻辑回归模型**
- css - bootstrap pull-left 和 pull-right 类不工作在角度