>>> mydict = {1: {45: 'ades', 54:'adee'}, 2: {68: 'gdes'}}
>>> curr_value = mydict[1][45]
>>> mydict[1][45] = 'zzzz'
>>> print (curr_value)
ades # Expected value: zzzz
我的curr_value
怎么没有从mydict
变异?我没有克隆curr_value
或任何东西。
答案 0 :(得分:0)
mydict = {1: {45: 'ades', 54:'adee'}, 2: {68: 'gdes'}}
curr_value = mydict[1][45]
mydict[1][45] = 'zzzz'
print (curr_value)
print(mydict)
输出:
ades
{1: {45: 'zzzz', 54: 'adee'}, 2: {68: 'gdes'}
你的字典是可变的 - 它被改变了。 curr_value
是一个字符串,不可变。
中间的想法:
def boll(tpl):
return mydict[tpl[0]][tpl[1]]
mydict = {1: {45: 'ades', 54:'adee'}, 2: {68: 'gdes'}}
curr_value = (1,45)
print (boll(curr_value))
mydict[1][45] = 'zzzz'
print (boll(curr_value))
这只是一个记忆你想要引用的dict中的点的封装,并且函数可以在你调用它时获得dict的值。
答案 1 :(得分:0)
当更新某些其他数据结构时,无法创建一个“更新”自身的普通变量。这种行为只能通过表达式来实现,比如属性或项目查找。换句话说,您可以创建一个对象curr_value
,以便评估curr_value[0]
在此时为您提供mydict[1][45]
的值,或者评估curr_value.value
会为您提供mydict[1][45]
的值1}}在那一刻,但是你无法做到这一点,因此仅仅评估普通curr_value
会给你mydict[1][45]
的价值。执行curr_value = mydict[1][45]
始终会将curr_value
设置为您分配时的内容,如果mydict[1][45]
发生更改,则不会在以后更新。
答案 2 :(得分:0)
您想要的是不可能的,因为简单的赋值总是创建一个新的绑定(即,将新对象绑定到=
符号的LHS上的名称)。 OTOH,执行突变不会创建新的绑定,所以你可以这样做,例如
ref = mydict[1]
mydict[1][45] = 'zzzz'
print(ref[45])
根据需要打印zzzz
。
Stack Overflow资深人士Ned Batchelder在Facts and myths about Python names and values中很好地介绍了这个主题,并在Other languages have "variables", Python has "names"中进行了总结。
另一个选择是
mydict = {1: {45: ['ades'], 54:['adee']}, 2: {68: ['gdes']}}
ref = mydict[1][45]
mydict[1][45][0]='zzzz'
print(ref[0])
一般来说,最好避免像这样造成混乱,但有时候这种事情很有用。例如,通过向2D列表添加额外的间接层,我们可以通过列和行来访问它。
# Create the grid
rows = [[[u+v] for u in 'abcd'] for v in 'wxyz']
cols = [list(u) for u in zip(*rows)]
print(rows)
print(cols)
print()
# Mutate some grid cells
cell = rows[1][2]
cell[0] = cell[0].upper()
cell = cols[0][3]
cell[0] = cell[0].upper()
print(rows)
print(cols)
<强>输出强>
[[['aw'], ['bw'], ['cw'], ['dw']], [['ax'], ['bx'], ['cx'], ['dx']], [['ay'], ['by'], ['cy'], ['dy']], [['az'], ['bz'], ['cz'], ['dz']]]
[[['aw'], ['ax'], ['ay'], ['az']], [['bw'], ['bx'], ['by'], ['bz']], [['cw'], ['cx'], ['cy'], ['cz']], [['dw'], ['dx'], ['dy'], ['dz']]]
[[['aw'], ['bw'], ['cw'], ['dw']], [['ax'], ['bx'], ['CX'], ['dx']], [['ay'], ['by'], ['cy'], ['dy']], [['AZ'], ['bz'], ['cz'], ['dz']]]
[[['aw'], ['ax'], ['ay'], ['AZ']], [['bw'], ['bx'], ['by'], ['bz']], [['cw'], ['CX'], ['cy'], ['cz']], [['dw'], ['dx'], ['dy'], ['dz']]]
在这个答案开始时,我说“简单分配总是创建一个新的绑定”。但是,augmented assignment将在可能的情况下执行就地操作,即目标是可变对象。来自文档:
可以将像
x += 1
这样的扩充分配表达式重写为x = x + 1
实现类似但不完全相同的效果。在里面 增强版本,x仅评估一次。另外,如果可能的话 实际操作是就地执行的,而不是 创建一个新对象并将其分配给目标,即旧对象 而是被修改了。