【问题标题】:Python - variable changes its value with no obvious reason in a recursive functionPython - 变量在递归函数中没有明显原因改变其值
【发布时间】:2019-05-28 03:33:38
【问题描述】:

我遇到了一个奇怪的行为——变量没有明显的原因改变了它的值。请帮助我了解发生这种情况的原因/原因以及如何避免这种情况。详细信息在下面作为内联 cmets 给出。为方便起见,将打印语句添加到代码中。

这个想法是通过将高阶数据相乘来展平 JSON 文件,如下所示。

非常感谢提前。

预期的输出是:

[{'records': '563'},
{'records': '563', 'id': '1111111', 'title': 'alignable', 'status': 'Completed'},
{'records': '563', 'id': '2222222', 'title': ' no links', 'status': 'something'}]

我的代码

test_json = {"records": "563",
             "campaign": [{"id": "1111111", "title": "alignable", "status": "Completed"},
                         {"id": "2222222", "title": " no links", "status": "something"}]
             }


def data_multiplication(initial_nested_data):
    out = [{}]

    def data_multiplication_(nested_data):
        if isinstance(nested_data, list) and len(nested_data) > 0:
            base_dic = out[-1]  # with the current example, this line should ( and is ) executed once only.
            # The main question is how it happens that base_dic changes from [{'records': '563'}]
            for x in nested_data:
                print(f'The base_dictionary before the desired append is: {base_dic}')
                # Works like a breeze when I append the out list with a static dic as below.
                out.append({1: 'This here should be the basic dictionary'})  # Comment this line to switch
                # Starts behaving abnormally if I append the out list as below. 
                # out.append(base_dic)  # Uncomment this line to switch
                print(f'The base_dictionary after the desired append is: {base_dic}')
                data_multiplication_(x)

        elif isinstance(nested_data, dict) or len(nested_data) == 0:
            for x in nested_data:
                if (isinstance(nested_data[x], list) or isinstance(nested_data[x], dict)) and len(nested_data[x]) > 0:
                    data_multiplication_(nested_data[x])
                else:
                    out[-1][x] = nested_data[x]

    data_multiplication_(initial_nested_data)

    return out


if __name__ == '__main__':
    result = data_multiplication(test_json)

【问题讨论】:

  • 程序的实际输出是什么?什么变量在变化?
  • append 不会复制。 Python 不会像在 C++ 中看到的那样隐式复制对象。
  • 请发送minimal reproducible example。 (最小的部分)

标签: python json python-3.x recursion


【解决方案1】:

您似乎使问题变得比必要的更难,或者您没有解释更多问题。鉴于您的示例输入和输出,这应该可以工作:

test_json = {
    "records": "563",
    "campaign": [
        {"id": "1111111", "title": "alignable", "status": "Completed"},
        {"id": "2222222", "title": " no links", "status": "something"}
    ]
}

def data_multiplication(initial_nested_data):
    out = [{}]

    def data_multiplication_recursive(nested_data):

        if isinstance(nested_data, dict):
            for key, value in nested_data.items():
                if isinstance(value, list):
                    data_multiplication_recursive(value)
                else:
                    out[0][key] = value

        elif isinstance(nested_data, list):
            base_dic = out[0]

            for dictionary in nested_data:
                out.append({**base_dic, **dictionary})

    data_multiplication_recursive(initial_nested_data)

    return out

if __name__ == '__main__':
    result = data_multiplication(test_json)
    print(result)

输出

[
    {'records': '563'},
    {'records': '563', 'id': '1111111', 'title': 'alignable', 'status': 'Completed'},
    {'records': '563', 'id': '2222222', 'title': ' no links', 'status': 'something'}
]

【讨论】:

  • 你太棒了,谢谢!当我用 out.append({**base_dic}) 替换 out.append(base_dic) 时,它起作用了。我希望我知道为什么...... :-) 另外我让它变得更难了,因为我希望它相对通用(更深的 json)
  • @AsenGeorgiev,对于单个字典,而不是 out.append({**base_dic}),您可以简单地执行 out.append(dict(base_dic)) 来强制复制。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
相关资源
最近更新 更多