我需要帮助来理解此代码中的意外依赖

时间:2019-01-03 12:56:59

标签: python dictionary dependencies

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

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是完全独立的实体。这怎么可能?

1 个答案:

答案 0 :(得分: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

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

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

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

PROFIT_LONG
2236442431176

并且当您对该列表进行突变时(再次ID 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:]}