Python 字典中的易变性
为什么我的Python 字典中的易变性,python,mutability,Python,Mutability,为什么我的curr\u值没有从mydict变异?我没有克隆curr\u value或任何东西 >>> mydict = {1: {45: 'ades', 54:'adee'}, 2: {68: 'gdes'}} >>> curr_value = mydict[1][45] >>> mydict[1][45] = 'zzzz' >>> print (curr_value) ades # Expected value: zzz
curr\u值
没有从mydict
变异?我没有克隆curr\u value
或任何东西
>>> 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
输出:
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'}
这只是封装了您想要引用的dict中的点,函数在调用dict时获取dict的值。无法创建一个普通变量,当其他数据结构更新时,该变量会自动“更新”。这种行为只能通过某种表达式实现,比如属性或项查找。换句话说,您可以创建一个对象curr\u value
,这样计算curr\u value[0]
时会得到mydict[1][45]
的值,或者计算curr\u value.value
时会得到mydict[1][45]
的值,但是你不能这样做,只计算普通的curr\u值
就可以得到此时的mydict[1][45]
。执行curr\u value=mydict[1][45]
始终将curr\u值设置为您分配它时的值,并且如果mydict[1][45]
发生更改,它将不会在以后更新。您想要的是不可能的,因为简单的分配总是创建一个新的绑定(即,将新对象绑定到=
符号LHS上的名称)。OTOH,执行变异不会创建新绑定,因此您可以这样做,例如
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))
根据需要打印zzzz
在中,堆栈溢出专家Ned Batchelder很好地介绍了此主题,并在中进行了总结
另一个选择是这样做
ref = mydict[1]
mydict[1][45] = 'zzzz'
print(ref[45])
一般来说,最好避免造成这样的混乱,但有时这类事情是有用的。例如,通过向2D列表添加额外的间接层,我们可以通过列和行访问它
mydict = {1: {45: ['ades'], 54:['adee']}, 2: {68: ['gdes']}}
ref = mydict[1][45]
mydict[1][45][0]='zzzz'
print(ref[0])
输出
# 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)
在回答的开头,我说“简单赋值总是创建一个新的绑定”。但是,如果可能,将执行就地操作,即目标是一个可变对象。从文档:
像x+=1
这样的增广赋值表达式可以重写为
x=x+1
以获得类似但不完全相同的效果
扩充版本,x只计算一次
实际操作在适当位置执行,这意味着
创建新对象并将其指定给目标,即旧对象
而是修改了
字符串是不可变的。当前值
不包含引用,因为它是字符串
对象,而不是列表
。哦……有没有方法引用“ades”点?你为什么要问字典?当前值
不引用字典对象,你可以简单地向自己演示f该字典已更改。它引用的字符串对象以前是,但现在不再是,也被mydict[1]
字典引用,因此被mydict
间接引用。您可能会发现这一点很有用:什么是“ades”点?您是指指针吗?您可以继续使用mydict[1][45]
,这是您分配给的。分配给curr\u value
也不会改变字典!您实际想要实现什么?mydict[1][45]
始终引用ADE的点。如果您保持[1]和[45]处于活动状态,则在您的情况下…@user13123:使用'mydict[1][45]“如果值发生变化。这样你就可以得到当前存储的任何内容。不需要那种(注意!)语言,而且你刚刚制作了一个有限版本。谢谢你的尝试!但是你的概念对我来说太先进了:(@jornsharpe在查找后更正了这些胡说八道-我没有那么“苛刻”翻译存储,大致如下。如果我在他的dict上使用f=itemgetter(1,45)
,我会得到一个itemerror-从docu中,它被用于1dim列表以获得倍数。是否存在一些“过载”对于这个用例?哦,对不起,我认为itemgetter
是深入的,而不是从一个级别提取多个项目。谢谢。我现在明白了。
[[['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']]]