【问题标题】:merging dicts not working as expected python 3.5合并dicts没有按预期工作python 3.5
【发布时间】:2018-01-02 08:16:16
【问题描述】:

这是 Python 3.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()

【问题讨论】:

  • 真的需要这么多代码来演示这个问题吗?
  • 不知道,总比不够好?
  • 当然,您可以将其最小化。根据您的问题的标题,我希望您的示例是两个字典,负责该确切逻辑的代码,显示它如何被破坏的输出,以及它应该是什么样子。
  • 将代码减少到复制问题所需的最小代码将 1) 大大改善答案 2) 提高您对问题的理解 3) 可能会帮助您自己解决问题
  • 我已经明确了,只需在你的 IDE 中复制过去就可以了

标签: python dictionary python-3.5


【解决方案1】:

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

out = {**out, **answer} # out is now a different object

由于函数是递归的,后续的修改不会影响到原来的dict。

不过,在第一个函数中,您只进行了项目分配,这会按预期修改 dict:

out[k] = v

【讨论】:

  • 我认为不可能在同一范围内创建 2 个具有相同 neme 的不同对象?
  • @DenisGantsev 该名称指的是任何给定时间的一个对象。赋值语句是当名称绑定到不同的对象时。
  • 哼,这有道理!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2014-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多