def is_safe(self,requesting_train_name,requesting_train_priority,requested_resources):
# Initialize P1 & P0
# We need to maintain an AR.
performer = requesting_train_name
AR = set(filter(lambda x : G.node[x]['reservation'] <= requesting_train_priority, G.nodes()))
P1 = []
P0 = self.active_trains.keys()
active_trains_trial = self.active_trains.copy()
print active_trains_trial is self.active_trains
# Update AR. Remove all elements of requested resources from AR
AR.difference_update(set(requested_resources))
# Provisionally updating OR
print 'OR before update',self.active_trains[performer].OR
active_trains_trial[performer].OR.update(set(requested_resources))
print 'OR after update',self.active_trains[performer].OR
“更新前的OR”和“更新后的OR”行应该给出相同的结果。这不会发生。 -is-语句按预期返回False。
答案 0 :(得分:0)
看起来您正在修改相同的字典并且解释器的行为正常。
>>> active_trains = {'one':1, 'two':2}
>>> active_trains_trial = active_trains
>>> active_trains_trial
{'two': 2, 'one': 1}
>>> active_trains_trial['one'] = 1.5
>>> active_trains
{'two': 2, 'one': 1.5}
如果您确实需要单独的字典,则必须创建副本。
答案 1 :(得分:0)
由于别名,这种情况正在发生。 print active_trains_trial is active_trains
应打印True
,但我希望您希望打印False
。这可以通过更改语句
active_trains_trial = active_trains
到
active_trains_trial = active_trains.copy()
进一步说明:
python中有两种对象: immutable 和 mutable 。 不可变对象的值无法更改。不可变对象包括数值,字符串和元组等。
而不是变量,python有标识符,它们只是指向对象的名称。您无法更改不可变对象本身的值,但您可以更改标识符指向的对象。例如:
var = 3
var = 4
不会更改int对象3
的值,而是将标识符 var
重新分配给int对象4
。
别名是指相同对象的不同名称。
var1 = 3
var2 = 3
是对不可变对象3
进行别名的示例。 var1
和var2
都是同一个对象,可以通过测试来证明id
是否相同。这可以在python中以两种方式完成:print var1 is var2
或print id(var1) == id(var2)
。这两个陈述都应打印True
。
但是,此特定示例仅适用于不可变对象。可以使用可变和不可变对象的一个例子是:
var1 = <object>
var2 = var1
使用 imutable 对象别名始终是安全的,因为对象本身的值永远不会意外更改。例如:
var1 = 3
var2 = var1
var2 = 4
print var1
print var2
print var1 is var2
将产生输出
3
4
False
请注意var1
的值如何不更改。
另一方面,可变对象的值,可以更改。可变对象包括列表和字典等。
L1 = [1, 2]
L2 = [1, 2]
L3 = L1
print L1 == L2
print L1 is L2
print L1 is L3
将产生输出
True
False
True
因为虽然L1
和L2
具有相同的值,但它们不相同的对象。虽然L3
被指定为到 L1
的对象,但他们 是同一个对象。
别名可变对象可能非常危险。这样做的原因是,如果您使用其中一个标识符 all 其他标识符&#39;更改对象的值。价值也会发生变化。
L1 = [1, 2, 3]
L2 = L1
L2 = [1, 2]
print L1
print L2
print L1 is L2
将产生输出
[1, 2]
[1, 2]
True
注意L1
的值如何变化。这是因为L1
和L2
只是相同可变对象的别名。
可以通过创建对象的副本来避免这种情况。使用列表可以将其完成为:L1 = <list>[:]
,使用词典可以完成:d1 = <dict>.copy()
L1 = [1, 2, 3]
L2 = L1[:]
L2 = [1, 2]
print L1
print L2
print L1 is L2
产生输出
[1, 2, 3]
[1, 2]
False
注意L1
的值没有变化,L1和L2不是同一个对象。
答案 2 :(得分:0)
我设法找到了问题所在。
当创建字典的副本时,可以创建映射的副本,而无需复制正在引用的对象。为了说明,当我检查active_trains_local是否为active_trains时,结果是假的,因为它是active_trains的浅表副本。但是,active_trains_local [执行者] 是 active_trains [执行者]。我终于写了一个duplicate_registery函数,它创建了一个字典,在active_trains上迭代,并填充了新的字典。
-- file: ch05/PrettyJSON.hs
module PrettyJSON
(
renderJValue
) where
import Numeric (showHex)
import Data.Char (ord)
import Data.Bits (shiftR, (.&.))
import SimpleJSON (JValue(..))
import Prettify (Doc, (<>), char, double, fsep, hcat, punctuate, text,
compact, pretty
这种情况下的值是namedtuples(来自collections模块)。所以,
def duplicate_registery(self):
duplicate_active_trains = {}
for name,dataset in self.active_trains.iteritems():
duplicate_active_trains[name] = train_data(copy(dataset.MR),copy(dataset.OR))
return duplicate_active_trains
不起作用,因为它制作了数据集的浅层副本,但即使在这个浅拷贝数据集中,MR和dataset.OR也引用了原始数据集所引用的同一对象。
获得的经验:浅写复制字典,给出映射的浅表副本。您最终得到的重复映射仍然引用相同的对象。特别感谢@Thomson