【问题标题】:I need help understanding unintended dependency in this code我需要帮助理解这段代码中的意外依赖
【发布时间】:2019-05-30 01:41:44
【问题描述】:

我创建了这个独立的示例来隔离我试图理解的行为:

from pprint import pprint

TRADES_CLOSED = dict()
TRADES_ACTIVE = {
    '2010-01-08 12:00': [1, 'SHORT', 20000, '2010-01-08 12:00', 92.339],
    '2010-01-28 04:00': [2, 'LONG', 10000, '2010-01-28 04:00', 90.378],
    '2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824],
    '2010-01-29 04:00': [4, 'LONG', 20000, '2010-01-29 04:00', 90.164]}

TRADES_TEST = {k: TRADES_ACTIVE[k] for k in sorted(TRADES_ACTIVE)[-2:]}

pprint(TRADES_ACTIVE)
pprint(TRADES_TEST)

profit_long = TRADES_ACTIVE.pop([key for key, value in TRADES_TEST.items() if value[1] == "LONG"][0])
profit_long.extend(['2010-02-03 12:00', 91.278, 1464.54])

pprint(TRADES_ACTIVE)
pprint(TRADES_TEST)

TRADES_CLOSED[[key for key, value in TRADES_TEST.items() if value[1] == "LONG"][0]] = profit_long

pprint(TRADES_CLOSED)

我想对TRADES_ACTIVE 字典中的最后两个条目执行一些操作。因此,我创建了一个名为TRADES_TEST 的新字典,其中仅包含来自TRADES_ACTIVE 的最后两个条目。

代码产生以下输出:

{'2010-01-08 12:00': [1, 'SHORT', 20000, '2010-01-08 12:00', 92.339],
 '2010-01-28 04:00': [2, 'LONG', 10000, '2010-01-28 04:00', 90.378],
 '2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824],
 '2010-01-29 04:00': [4, 'LONG', 20000, '2010-01-29 04:00', 90.164]}
{'2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824],
 '2010-01-29 04:00': [4, 'LONG', 20000, '2010-01-29 04:00', 90.164]}
{'2010-01-08 12:00': [1, 'SHORT', 20000, '2010-01-08 12:00', 92.339],
 '2010-01-28 04:00': [2, 'LONG', 10000, '2010-01-28 04:00', 90.378],
 '2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824]}
{'2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824],
 '2010-01-29 04:00': [4,
                      'LONG',
                      20000,
                      '2010-01-29 04:00',
                      90.164,
                      '2010-02-03 12:00',
                      91.278,
                      1464.54]}
{'2010-01-29 04:00': [4,
                      'LONG',
                      20000,
                      '2010-01-29 04:00',
                      90.164,
                      '2010-02-03 12:00',
                      91.278,
                      1464.54]}

profit_long 列表是通过弹出TRADES_ACTIVE 的特定元素创建的。正如所料TRADES_ACTIVE 短一个元素。然后profit_long 被三个新值扩展并用作TRADES_CLOSED 字典中的条目。

我不明白,为什么扩展profit_long 也会影响TRADES_TEST。我盯着这段代码看了很长时间,我想不通。对我来说profit_longTRADES_TEST 是完全独立的实体。这怎么可能?

【问题讨论】:

    标签: python dictionary dependencies


    【解决方案1】:

    您的依赖是由于您的代码设置了一个名为TRADES_ACTIVE 的列表字典,然后它将其中一些列表复制到另一个名为TRADES_TEST 的列表字典。但是,当您将列表分配给另一个变量时,该分配不会复制列表;它只复制 对它的引用。要看到这一点,在您的每个 pprint() 呼叫之后,请为 k,v in somedict.items(): print (k, id(v)) 执行操作。这将向您显示每个列表的 ID。当我这样做时,这就是我所看到的。先上代码:

    print("TRADES ACTIVE 1")
    pprint(TRADES_ACTIVE)
    print("TRADES ACTIVE 1")
    for k,v in TRADES_ACTIVE.items(): print (k, id(v))
    
    print("TRADES TEST 1")
    pprint(TRADES_TEST)
    print("TRADES TEST 1")
    for k,v in TRADES_TEST.items(): print (k, id(v))
    

    然后是输出:

    TRADES ACTIVE 1
    {'2010-01-08 12:00': [1, 'SHORT', 20000, '2010-01-08 12:00', 92.339],
     '2010-01-28 04:00': [2, 'LONG', 10000, '2010-01-28 04:00', 90.378],
     '2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824],
     '2010-01-29 04:00': [4, 'LONG', 20000, '2010-01-29 04:00', 90.164]}
    TRADES ACTIVE 1
    2010-01-08 12:00 2236442430536
    2010-01-28 04:00 2236442430856
    2010-01-28 12:00 2236442431048
    2010-01-29 04:00 2236442431176
    TRADES TEST 1
    {'2010-01-28 12:00': [3, 'SHORT', 10000, '2010-01-28 12:00', 89.824],
     '2010-01-29 04:00': [4, 'LONG', 20000, '2010-01-29 04:00', 90.164]}
    TRADES TEST 1
    2010-01-28 12:00 2236442431048
    2010-01-29 04:00 2236442431176
    

    如您所见,两个 dicts 中的匹配键指向同一个列表。请注意,id 2236442431176 在两个列表中都作为键“2010-01-29 04:00”的值重复出现。

    然后,您的代码会复制其中一个名为 profit_long 的列表。这也指的是在其他两个字典中作为值出现的同一个列表。

    print("PROFIT_LONG")
    print (id(profit_long))
    
    PROFIT_LONG
    2236442431176
    

    当您更改该列表(再次为 2236442431176)时,更改在两个字典中可见,因为所有三个变量都引用同一个列表。

    要解决此问题,当您复制列表对象时,请复制列表而不仅仅是对其的引用。所以,而不是

    TRADES_TEST = {k: TRADES_ACTIVE[k] for k in sorted(TRADES_ACTIVE)[-2:]}
    

    TRADES_TEST = {k: TRADES_ACTIVE[k][:] for k in sorted(TRADES_ACTIVE)[-2:]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      相关资源
      最近更新 更多