Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:转换深度嵌套字典或数组中的类型_Python_Dictionary_Nested - Fatal编程技术网

Python:转换深度嵌套字典或数组中的类型

Python:转换深度嵌套字典或数组中的类型,python,dictionary,nested,Python,Dictionary,Nested,我编写了以下帮助函数来将ObjectID(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 retur

我编写了以下帮助函数来将ObjectID(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'}


但是,对于数组中的对象和对象内部的对象,它似乎失败了。我想知道是否有更好的方法来迭代嵌套的iterables和转换类型?

我认为如果您将转换放在一开始,这将更容易解释,允许递归调用传递
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
    if isinstance(d, dict):
        return {k:clean_dict_helper(v) for k, v in d.items() }
电话:

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可能是有意义的,而不是使用以下内容对传入的值进行变异:

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
    if isinstance(d, dict):
        return {k:clean_dict_helper(v) for k, v in d.items() }

你所说的“对象内部的数组”是什么意思,你实际上是指“字典内部的数组”吗?因为对于
d
类型的
ObjectId
没有子句可以查看
ObjectId
的内部,所以这可以解释您的问题吗?我已经编辑了您的问题,为
ObjectId
添加了一个示例和一个模拟类,但它似乎工作正常?输出是
{1:{1:'test1',2:['test2','test3'],3:'2020-01-01 00:00:00',4:[{1:'test4'}]},2:['test5','test6']}
这似乎是您所需要的?我包括了一个突破性的测试用例。