【问题标题】:Python code produces incorrect results without using the .COPY() functionPython 代码在不使用 .COPY() 函数的情况下产生不正确的结果
【发布时间】:2017-11-30 15:40:16
【问题描述】:

我有这个代码。

List1 = [{'pg_id': 100, "group_name": "test1", "product_price": 100}, {'pg_id': 200, "group_name": "test2", "product_price": 200}]
List2 = [{'lowest_price': 20}]

FINAL_DICT = {}
for latest_lowest in List1:
    for idx, coupon_related__product in enumerate(List2):
        if coupon_related__product['lowest_price'] < latest_lowest['product_price']:
            FINAL_DICT[ latest_lowest['pg_id'] ] = coupon_related__product
            FINAL_DICT[ latest_lowest['pg_id'] ]['group_name'] = latest_lowest['group_name']
            print("Group name is %s"%(latest_lowest['group_name']))

for PG_ID, LOWEST_PRICED_PRODUCT_THIS_PG in FINAL_DICT.iteritems():
    print(LOWEST_PRICED_PRODUCT_THIS_PG)

我想要的终端输出是

Group name is test1
Group name is test2
{'lowest_price': 20, 'group_name': 'test2'}
{'lowest_price': 20, 'group_name': 'test1'}

但它输出

Group name is test1
Group name is test2
{'lowest_price': 20, 'group_name': 'test2'}
{'lowest_price': 20, 'group_name': 'test2'}

如果我改变了

FINAL_DICT[ latest_lowest['pg_id'] ] = coupon_related__product

FINAL_DICT[ latest_lowest['pg_id'] ] = coupon_related__product.copy()

然后它会产生我想要的正确输出。

我的问题是,为什么FINAL_DICT 中的所有字典都有group_name=test2 而我不使用.copy()

【问题讨论】:

    标签: python logic


    【解决方案1】:

    这一行:

    FINAL_DICT[ latest_lowest['pg_id'] ] = coupon_related__product
    

    为您的条目分配字典。下一行:

    FINAL_DICT[ latest_lowest['pg_id'] ]['group_name'] = latest_lowest['group_name']
    

    更改组名,但字典的引用是您分配给的最后一个字典,因此引用是共享的。

    这就是为什么你必须复制 dict 以便引用是独立的:

    FINAL_DICT[ latest_lowest['pg_id'] ] = coupon_related__product.copy()
    

    现在修改FINAL_DICT[ latest_lowest['pg_id'] ]['group_name']不会改变其他FINAL_DICT[ latest_lowest['pg_id'] ]的值

    【讨论】:

    • 这个东西在Python中叫什么?能否提供一个非常简单的示例代码?
    • “这个东西”,你的意思是引用?什么的示例代码?
    • “冻结”是真正的 Python 术语吗?
    • 不。这叫做复制。不确定它是否真的与python相关
    【解决方案2】:

    在 Python 中,字典是可变对象,因此默认情况下不会被复制。您可以在此处阅读更多相关信息:python dictionary passed as an input to a function acts like a global in that function rather than a local

    如果整个按名称传递、按值传递和按引用传递的事情太令人困惑,那么您只需要知道 Python 在使用 @ 分配值时通常不会复制 listdict 987654324@。当你想要复制 listdict 时,你需要明确告诉 Python 你想要一个副本。所以总结一下

    x = {"hello": "world"}
    y = x
    y["hello"] = "not world"
    print("x is " + str(x))
    print("y is " + str(y))
    
    > x is {'hello': 'not world'}
    > y is {'hello': 'not world'}
    

    x = {"hello": "world"}
    y = x.copy()
    y["hello"] = "not world"
    print("x is " + str(x))
    print("y is " + str(y))
    
    > x is {'hello': 'world'}
    > y is {'hello': 'not world'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-14
      • 2015-10-12
      • 2015-01-06
      • 2021-08-22
      相关资源
      最近更新 更多