首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >迭代列表上的字典将更新所有元素,而不是当前元素

迭代列表上的字典将更新所有元素,而不是当前元素
EN

Stack Overflow用户
提问于 2021-03-24 22:43:20
回答 1查看 19关注 0票数 1

我正在通过列表理解生成一个字典列表,该列表理解根据输入参数scope_1将元素重复x次。

当我迭代这个字典列表时,我向其中添加了一些新的键和值。但它不是只更新迭代中列表的当前元素,而是更新列表中的所有元素(Dict),所以我在最后一次循环执行中使用具有相同数据的所有元素来结束它。

为了检查我是否正确地创建了这个列表,我手动重新创建了它,并将其硬编码并添加为我的函数scope_2的第二个返回,并且这个新列表工作得很好。但我看不出这两个列表之间有任何不同的行为。

代码语言:javascript
复制
def get_test_scope(request):
    repeat = request

    test_object = {}
    # Reads from file
    test_object["id"] = "ID-1"
    test_object["summary"] = "Summary-1"

    # Scope 1 from list comprehension
    scope_1 = [test_object for _ in range(repeat)]

    # Scope 2 created manually
    scope_2 = [
        {"id": "ID-2", "summary": "Summary-2"},
        {"id": "ID-2", "summary": "Summary-2"},
    ]
    return scope_1, scope_2


if __name__ == "__main__":
    import random
    # how many times to replicate element inside list
    scope_1, scope_2 = get_test_scope(2)

    # Prints Scope 1 and Scope 2
    print(f"Scope_1: {scope_1}")
    print(f"Scope_2: {scope_2}")

    # Iterates over Scope 1 and add new key, value pairs to it
    # FAIL: Should update only current test element. But updates all the elements of the list in each iteration
    for index, test in enumerate(scope_1):
        test["run"] = index
        test["duration"] = random.randint(1, 10)
        print(f"Scope 1: Loop({index}): {scope_1}")

    # Iterates over Scope 2 and add new key, value pairs to it
    # OK: Adds only to the current test element. Items end it up with their respective values
    for index, test in enumerate(scope_2):
        test["run"] = index
        test["duration"] = random.randint(1, 10)
        print(f"Scope 2: Loop({index}): {scope_2}")

我有一个比较作用域1和作用域2的输出,我找不到区别,也不能理解第一个行为。

代码语言:javascript
复制
Scope_1: [{'id': 'ID-1', 'summary': 'Summary-1'}, {'id': 'ID-1', 'summary': 'Summary-1'}]
Scope_2: [{'id': 'ID-2', 'summary': 'Summary-2'}, {'id': 'ID-2', 'summary': 'Summary-2'}]
Scope 1: Loop(0): [{'id': 'ID-1', 'summary': 'Summary-1', 'run': 0, 'duration': 1}, {'id': 'ID-1', 'summary': 'Summary-1', 'run': 0, 'duration': 1}]
Scope 1: Loop(1): [{'id': 'ID-1', 'summary': 'Summary-1', 'run': 1, 'duration': 8}, {'id': 'ID-1', 'summary': 'Summary-1', 'run': 1, 'duration': 8}]
Scope 2: Loop(0): [{'id': 'ID-2', 'summary': 'Summary-2', 'run': 0, 'duration': 6}, {'id': 'ID-2', 'summary': 'Summary-2'}]
Scope 2: Loop(1): [{'id': 'ID-2', 'summary': 'Summary-2', 'run': 0, 'duration': 6}, {'id': 'ID-2', 'summary': 'Summary-2', 'run': 1, 'duration': 1}]
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-24 22:53:10

执行scope_1 = [test_object for _ in range(repeat)]时,您不是在创建test_object的副本。您只是创建了一个对test_object的引用列表。这意味着scope_1[0]scope_1[1]都指向同一个字典。

要解决此问题,请在理解列表中创建字典的副本:

代码语言:javascript
复制
scope_1 = [test_object.copy() for _ in range(repeat)]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66783446

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档