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

标签 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 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']}

此外,由于您正在使用理解来创建一个新列表,因此返回一个新的字典可能是有意义的,而不是使用以下内容来改变传入的值:

    if isinstance(d, dict):
        return {k:clean_dict_helper(v) for k, v in d.items() }

关于Python:转换深层嵌套字典或数组中的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59605943/

相关文章:

python - 使用 suds 在 SOAP 请求中多次发送相同类型

python - 从 Scrapy pipeline 中培养 close spider

python - 如何按类型选择数据框中的列

python - 编写一个 for 循环来打印 1 个嵌套字典的键

python - 使用预定义键创建字典

android - 映射外部字符串android

javascript - 使用方形 backets 设置嵌套对象的值返回 undefined

python - 无法将 spark 数据框列与 df.withColumn() 合并

Linq to SQL 嵌套选择组(按计数)

python - 使用 python 将嵌套列表转换为行