合并dict未按预期运行python 3.5

合并dict未按预期运行python 3.5,python,dictionary,python-3.5,Python,Dictionary,Python 3.5,这是Python3.5环境,我认为代码是不言自明的,在这里,我希望两个函数都能工作,但只有一个是正确的 TLDR: 分配out={**out,**answer}使out变量包含正确的键,但在接下来的两个步骤中它们丢失;当分配c={**c时,**a}在测试函数中工作良好,并且新的键不会丢失 有人能解释一下我做错了什么吗 def flatify_works(d, out, fhook=None): for k, v in d.items(): if not isinstanc

这是Python3.5环境,我认为代码是不言自明的,在这里,我希望两个函数都能工作,但只有一个是正确的

TLDR: 分配
out={**out,**answer}
使
out
变量包含正确的键,但在接下来的两个步骤中它们丢失;当分配
c={**c时,**a}
在测试函数中工作良好,并且新的键不会丢失

有人能解释一下我做错了什么吗

def flatify_works(d, out, fhook=None):
    for k, v in d.items():
        if not isinstance(v, dict) and not isinstance(v, list):
            out[k] = v
        elif isinstance(v, dict):
            flatify_works(v, out, fhook)
        elif isinstance(v, list):
            if fhook is None:
                raise AssertionError("an array with more than 1 elment found.")
            answer = fhook(k, v)
            for k, v in answer.items():
                out[k] = v


def flatify_doesnt_work(d, out, fhook=None):
    for k, v in d.items():
        if not isinstance(v, dict) and not isinstance(v, list):
            out[k] = v
        elif isinstance(v, dict):
            flatify_doesnt_work(v, out, fhook)
        elif isinstance(v, list):
            if fhook is None:
                raise AssertionError("an array with more than 1 elment found.")
            answer = fhook(k, v)
            out = {**out, **answer}  # put a breakpoint here, and go 2 steps further


def hook(k, v):
    l = [d["c"] for d in v]
    return {"c": sum(l), "d": "blabla"}


def test_merge_dicts():
    a = {"a": 1, "b": 2}
    c = {"c": 3}
    c = {**c, **a}  # merging works perfectly here
    print(c)
    assert "a" in c and "b" in c and "c" in c  # ok


def test_nested_works():
    out = {}
    flatify_works({"a": 1, "b": [{"c": 0.6, "d": 4}, {"c": 0.4, "d": 4}]}, out, hook)
    print("working exemple: {}".format(str(out)))


def test_nested_doesnt_work():
    out = {}
    flatify_doesnt_work({"a": 1, "b": [{"c": 0.6, "d": 4}, {"c": 0.4, "d": 4}]}, out, hook)
    print("not working exemple: {}".format(str(out)))


def main():
    test_merge_dicts()  # ok
    test_nested_works() # ok
    test_nested_doesnt_work() # why out = {**out, **answer} is not working as expected?


if __name__ == '__main__':
    main()

我认为区别在于,在第二个函数中,您重新分配了
out
变量,之后它与传递到函数中的dict分离:

out = {**out, **answer} # out is now a different object
由于函数是递归的,因此后续修改不会影响原始dict

但是,在第一个函数中,您只执行项目分配,这将按照预期修改dict:

out[k] = v

我认为区别在于,在第二个函数中,您重新分配了
out
变量,之后它与传递到函数中的dict分离:

out = {**out, **answer} # out is now a different object
由于函数是递归的,因此后续修改不会影响原始dict

但是,在第一个函数中,您只执行项目分配,这将按照预期修改dict:

out[k] = v

真的需要那么多的代码来演示这个问题吗?我不知道,这比不够好吗?当然,您可以将其最小化。根据你问题的标题,我希望你的例子是两个字典,负责精确逻辑的代码,显示它如何被破坏的输出,以及它应该是什么样子。将代码缩减到复制问题所需的最小值将1)大大改进答案2)提高对问题的理解3)可能有助于您自己解决问题我将其明确化,只需在IDE中复制过去,它将工作,那么多的代码真的需要证明这个问题?我不知道,这是比不够好吗?当然,你可以尽量减少这一点。根据你问题的标题,我希望你的例子是两个字典,负责精确逻辑的代码,显示它如何被破坏的输出,以及它应该是什么样子。将代码缩减到复制问题所需的最小值将1)大大改进答案2)提高对问题的理解3)可能有助于您自己解决问题我将其明确化,只需在IDE中复制过去,我认为不可能在同一范围内用同一个neme创建两个不同的对象?@DenisGantsev该名称在任何给定时间都指一个对象。赋值语句是当名称绑定到另一个对象时使用的。哼,这会使sens!我认为不可能在同一范围内用同一个neme创建两个不同的对象?@DenisGantsev该名称在任何给定时间都指向一个对象。赋值语句是当名称绑定到另一个对象时使用的。哼,这会使sens!