我不理解Python 2.7.12 ...
的这种行为请验证下面粘贴的代码:
test = [(('AAA_1', 'BBB_1', 'CCC_1'), 1), (('AAA_2', 'BBB_2', 'CCC_2'), 2),(('AAA_3', 'BBB_3', 'CCC_3'), 3), (('AAA_4', 'BBB_4', 'CCC_4'), 4)]
for i, j in enumerate(test):
for k, l in enumerate(j[0]):
if k == 0:
dc['first'] = l
elif k == 1:
dc['second'] = l
elif k == 2:
dc['third'] = l
elif k == 3:
dc['fourth'] = l
c.append(dc)
print "/n"
print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx"
print dc
print json.dumps(c, indent=1)
print c
print json.dumps(c, indent=1)
上面显示的代码结果存储在公共pastebin:http://pastebin.com/GkrTyseg
中对我来说有点奇怪: 通过附加列表:c我想收到词典列表。这个词典可以代表每种类型的AAA,BBB,CCC元组。我使用字典将其转换为json,以便通过webservices轻松地使用这些数据。
无论如何,我希望收到json:
{
"second": "BBB_1",
"third": "CCC_1",
"first": "AAA_1"
},
{
"second": "BBB_2",
"third": "CCC_2",
"first": "AAA_2"
},
{
"second": "BBB_3",
"third": "CCC_3",
"first": "AAA_3"
},
{
"second": "BBB_4",
"third": "CCC_4",
"first": "AAA_4"
}
但实际结果是:
{
"second": "BBB_4",
"third": "CCC_4",
"first": "AAA_4"
},
{
"second": "BBB_4",
"third": "CCC_4",
"first": "AAA_4"
},
{
"second": "BBB_4",
"third": "CCC_4",
"first": "AAA_4"
},
{
"second": "BBB_4",
"third": "CCC_4",
"first": "AAA_4"
}
为什么之前附加的值会将其值更改为新值?
当我使用而不是list时,我收到了相同的结果:c使用额外的字典,以获得比使用列表更漂亮的json。但结果是一样的...... 我尝试使用(而不是列表:c):
main_dc[i+1] = dc
如何防止不更改列表或字典元素的值?
答案 0 :(得分:0)
您应该将字典的副本附加到列表中(实际上是一个新的字典,其引用不是dc
),因此不会对先前附加的同一对象进行字典的进一步更改: / p>
c.append(dc.copy())
答案 1 :(得分:0)
你可以使用深copy(虽然还有其他方法)。当你不使用深度并使用引用的类似对象时,就会发生这种情况!这里是您的代码更改深拷贝,并正常工作:
import copy
import json
test = [(('AAA_1', 'BBB_1', 'CCC_1'), 1), (('AAA_2', 'BBB_2', 'CCC_2'), 2),(('AAA_3', 'BBB_3', 'CCC_3'), 3), (('AAA_4', 'BBB_4', 'CCC_4'), 4)]
c = []
for i, j in enumerate(test):
dc = copy.deepcopy({}) #or simply dc = {}
for k, l in enumerate(j[0]):
if k == 0:
dc['first'] = l
elif k == 1:
dc['second'] = l
elif k == 2:
dc['third'] = l
elif k == 3:
dc['fourth'] = l
c.append(dc)
print "/n"
print "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXx"
print dc
print json.dumps(c, indent=1)
print c
print json.dumps(c, indent=1)
这是一个很好的例子,可以看到深拷贝和浅拷贝的区别
In [1]: l1 = [1,2,3,4]
In [2]: l2 = l1
In [3]: l3 = copy.deepcopy(l1) #import copy
In [4]: l2[0] = 0
In [5]: l1
Out[5]: [0, 2, 3, 4]
In [6]: l2
Out[6]: [0, 2, 3, 4]
In [7]: l3
Out[7]: [1, 2, 3, 4]
答案 2 :(得分:0)
在您的代码中缺少dc
的定义,但我假设您在所有循环之前定义。这意味着您不会在每次迭代中生成新的dc
对象。相反,您重复使用第一个,覆盖其内容,并将其一次又一次地附加到c
。 "追加"这意味着,指向同一对象的四个链接将附加到c
。
在进入dc
循环之前,您应该在i, j
循环内移动k, l
的定义。这会在i, j
循环的每次迭代中创建一个新对象。
...
for i, j in enumerate(test):
dc = {}
for k, l in enumerate(j[0]):
...