我创建了这个独立的示例来隔离我想了解的行为:
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_long
和TRADES_TEST
是完全独立的实体。这怎么可能?
答案 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:]}