python - 如何比较嵌套的字典

标签 python dictionary search hash set

a_standard = {
    'section1': {
        'category1': 1,
        'category2': 2
    },
    'section2': {
        'category1': 1,
        'category2': 2
    }

}

a_new = {
    'section1': {
        'category1': 1,
        'category2': 2
    },
    'section2': {
        'category1': 1,
        'category2': 3
    }

}

我想找到 a_standarda_new 之间的区别,它在 a_new[section2][category2] 中的区别是 23

我应该将每个转换为一个集合,然后进行差分还是循环比较字典?

最佳答案

有一个图书馆叫deepdiff有很多选项,但我发现它有点不直观。

这是我在单元测试期间经常用来计算差异的递归函数。这超出了问题的范围,因为我也处理了嵌套列表的情况。我希望你会发现它有用。

函数定义:

from copy import deepcopy


def deep_diff(x, y, parent_key=None, exclude_keys=[], epsilon_keys=[]):
    """
    Take the deep diff of JSON-like dictionaries

    No warranties when keys, or values are None

    """
    EPSILON = 0.5
    rho = 1 - EPSILON

    if x == y:
        return None

    if parent_key in epsilon_keys:
        xfl, yfl = float_or_None(x), float_or_None(y)
        if xfl and yfl and xfl * yfl >= 0 and rho * xfl <= yfl and rho * yfl <= xfl:
            return None

    if type(x) != type(y) or type(x) not in [list, dict]:
        return x, y

    if type(x) == dict:
        d = {}
        for k in x.keys() ^ y.keys():
            if k in exclude_keys:
                continue
            if k in x:
                d[k] = (deepcopy(x[k]), None)
            else:
                d[k] = (None, deepcopy(y[k]))

        for k in x.keys() & y.keys():
            if k in exclude_keys:
                continue

            next_d = deep_diff(x[k], y[k], parent_key=k, exclude_keys=exclude_keys, epsilon_keys=epsilon_keys)
            if next_d is None:
                continue

            d[k] = next_d

        return d if d else None

    # assume a list:
    d = [None] * max(len(x), len(y))
    flipped = False
    if len(x) > len(y):
        flipped = True
        x, y = y, x

    for i, x_val in enumerate(x):
        d[i] = deep_diff(y[i], x_val, parent_key=i, exclude_keys=exclude_keys, epsilon_keys=epsilon_keys) if flipped else deep_diff(x_val, y[i], parent_key=i, exclude_keys=exclude_keys, epsilon_keys=epsilon_keys)

    for i in range(len(x), len(y)):
        d[i] = (y[i], None) if flipped else (None, y[i])

    return None if all(map(lambda x: x is None, d)) else d

# We need this helper function as well:
def float_or_None(x):
    try:
        return float(x)
    except ValueError:
        return None

用法:

>>> deep_diff(a_standard, a_new)

{'section2': {'category2': (2, 3)}}

我认为输出比其他答案更直观一些。

在单元测试中我会这样:

import json

diff = deep_diff(expected_out, out, exclude_keys=["flickery1", "flickery2"])
assert diff is None, json.dumps(diff, indent=2)

关于python - 如何比较嵌套的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48652762/

相关文章:

python - Pandas MultiIndex(超过 2 个级别)DataFrame 到嵌套 Dict/JSON

visual-studio - VsVim:替换视觉突出显示部分中的文本

search - vim 中的字符串完全匹配? (就像在less中的 'regex-off'模式。)

arrays - 字典中每个项目的第一个成员需要是一个数组

MySQL 中的 PHP 搜索

python - 为什么FastAPI从路由函数返回时会执行两次Pydantic构造函数?

python - SA : can I have a 'year' column_property for a Date column?

python - 如何从回调中生成调用生成器的值

python - 有什么方法可以使用 vscode 在绘图查看器中显示交互式绘图吗?

c# - 将 2 个字典项聚合到一个对象中