将另一个字典添加为值时,词典无法正确更新

时间:2017-05-09 14:15:40

标签: python dictionary

我试图将字典存储在一个主字典中,作为存储变量历史的一种方式,以便以后可以访问它们,如果需要的话。

我将字典定义为:

self.current = {}
self.version = {}

self.current将存储两个键/值对,它们将单词nodes映射到当前节点SQL表,将单词edges映射到当前边缘SQL表。

当程序迭代时,它会创建新表来表示系统中的边和节点,因此我希望将self.current本身存储为self.version中的值,以便{ {1}}变量可以在任何过去的时间步骤访问系统的状态。

例如,如果共有10次迭代,则time应返回self.current['nodes']'dhn_vertices_pgr9'应返回self.current['edges']

我这样做:

'dhn9'

每次迭代结束时。然而,self.version[time] = self.current 表每次都将最新的字典映射到每个时间步骤:

使用印刷声明:

self.version

在控制台中显示:

print('iteration {0}, current nodes = {1}'.format(time, self.current['nodes']))
print('iteration {0}, current edges = {1}'.format(time, self.current['edges']))
print('iteration {0}, time = {1}'.format(time, time))
print('iteration {0}, self.current = {1}'.format(time, self.current))
self.version[time] = self.current
print('iteration {0}, self.version = {1}\n'.format(time, self.version))

如您所见,iteration 0, current nodes = dhn_0_vertices_pgr iteration 0, current edges = dhn_0 iteration 0, time = 0 iteration 0, self.current = {'edges': 'dhn_0', 'nodes': 'dhn_0_vertices_pgr'} iteration 0, self.version = {0: {'edges': 'dhn_0', 'nodes': 'dhn_0_vertices_pgr'}} iteration 1, current nodes = dhn_1_vertices_pgr iteration 1, current edges = dhn_1 iteration 1, time = 1 iteration 1, self.current = {'edges': 'dhn_1', 'nodes': 'dhn_1_vertices_pgr'} iteration 1, self.version = {0: {'edges': 'dhn_1', 'nodes': 'dhn_1_vertices_pgr'}, 1: {'edges': 'dhn_1', 'nodes': 'dhn_1_vertices_pgr'}} iteration 2, current nodes = dhn_2_vertices_pgr iteration 2, current edges = dhn_2 iteration 2, time = 2 iteration 2, self.current = {'edges': 'dhn_2', 'nodes': 'dhn_2_vertices_pgr'} iteration 2, self.version = {0: {'edges': 'dhn_2', 'nodes': 'dhn_2_vertices_pgr'}, 1: {'edges': 'dhn_2', 'nodes': 'dhn_2_vertices_pgr'}, 2: {'edges': 'dhn_2', 'nodes': 'dhn_2_vertices_pgr'}} iteration 3, current nodes = dhn_3_vertices_pgr iteration 3, current edges = dhn_3 iteration 3, time = 3 iteration 3, self.current = {'edges': 'dhn_3', 'nodes': 'dhn_3_vertices_pgr'} iteration 3, self.version = {0: {'edges': 'dhn_3', 'nodes': 'dhn_3_vertices_pgr'}, 1: {'edges': 'dhn_3', 'nodes': 'dhn_3_vertices_pgr'}, 2: {'edges': 'dhn_3', 'nodes': 'dhn_3_vertices_pgr'}, 3: {'edges': 'dhn_3', 'nodes': 'dhn_3_vertices_pgr'}} 中的每个值都只是最新的条目。

但对我来说没有意义的是,如果我只是将这两个条目保存为像这样的元组:

self.version

再次使用印刷声明:

self.version[time] = (self.current['edges'], self.current['nodes'])

提供控制台输出:

print('iteration {0}, current nodes = {1}'.format(time, self.current['nodes']))
print('iteration {0}, current edges = {1}'.format(time, self.current['edges']))
print('iteration {0}, time = {1}'.format(time, time))
print('iteration {0}, self.current = {1}'.format(time, self.current))
self.version[time] = (self.current['edges'], self.current['nodes'])
print('iteration {0}, self.version = {1}\n'.format(time, self.version))

正如您所看到的,时间步骤1现在实际上映射到表格名称,因为它们在时间步骤1中,时间步骤2映射到表格名称,如时间步骤2,表格名称3到时间步骤3,等等...

那么为什么在字典中这样做会导致它失败,当用元组做这件事时效果很好?

1 个答案:

答案 0 :(得分:2)

分配时

self.version[time] = (self.current)

您没有指定dict的值,而是指向同一个dict的引用。请考虑以下示例:

dictA = {}
dictB = {}
dictA = dictB
dictB['foo'] = 'bar'
print(dictA) //{'foo': 'bar'}
print(dictB) //{'foo': 'bar'}

在此示例中,当您指定dictA = dictB时,您将dictAdictB指向同一个对象。因此,更改dictB也会更改dictA(相反)要解决此问题,您需要复制dictB(而不是参考) 。你可以按dict(dictB)执行此操作,根据:

dictA = {}
dictB = {}
dictA = dict(dictB) //the value of dictB is now copied, not the reference
dictB['foo'] = 'bar'
print(dictA) //{}
print(dictB) //{'foo': 'bar'}

回到您的示例:更改self.current也会影响self.version。因此,要将此更改修复为:

self.version[time] = dict(self.current)

请参阅How to copy a dictionary and only edit the copy