python - 为什么 'x = x + something' 不返回与 'x += something' 相同的结果?
问题描述
我正在尝试创建一个函数sprout_leaves
,该函数会在原始树 t 中的每个叶子处生成新叶子,其中包含叶子中的数据并返回结果树。
所以,输出会是这样的
>>> t1 = tree(1, [tree(2), tree(3)])
>>> print_tree(t1)
1
2
3
>>> new1 = sprout_leaves(t1, [4, 5])
>>> print_tree(new1)
1
2
4
5
3
4
5
>>> t2 = tree(1, [tree(2, [tree(3)])])
>>> print_tree(t2)
1
2
3
>>> new2 = sprout_leaves(t2, [6, 1, 2])
>>> print_tree(new2)
1
2
3
6
1
2
现在我的函数看起来像这样:
def sprout_leaves(t, leaves):
leaves_as_tree = branches(tree('', [tree(x) for x in leaves]))
if not is_leaf(t):
for b in branches(t):
if is_leaf(b):
b += leaves_as_tree # !!!
else:
return tree(label(t),[(sprout_leaves(tree(label(b), branches(b)), leaves))])
return t
此函数为我返回所需的结果:
>>> t1 = tree(1, [tree(2), tree(3)])
>>> new1 = sprout_leaves(t1, [4, 5])
>>> print_tree(new1)
1
2
4
5
3
4
5
但是,如果我更改b += leave_as_tree
为b = b + leaves_as_tree
,则输出更改为:
>>> t1 = tree(1, [tree(2), tree(3)])
>>> new1 = sprout_leaves(t1, [4, 5])
>>> print_tree(new1)
1
2
3
我的问题很简单:为什么会这样?无论我尝试什么,如果我不使用+=
,输出都会出错。
要重现此示例,以下是所需的功能:
解决方案
b = b + leaves_as_tree
做了几件事:
- 来电
b.__add__(leaves_as_tree)
- 将该操作的结果分配给 name
b
。现在b
指向与以前不同的对象。
b += leaves_as_tree
是不同的:
- 它调用
b.__iadd__(leaves_as_tree)
- ……就是这样。
所以真正的区别是b = b + leaves_as_tree
创建一个新对象然后更新b
指向它,但b += leaves_as_tree
调用一个函数来改变 b 到位。
object.__iadd__
(注意:必须在适当的位置改变对象并没有什么神奇的,但是如果某个类将其定义为做一些不同的事情,那么每个人都会对该类的作者感到恼火。)
list
这是使用内置类的示例:
>>> a = []
>>> id(a)
4315491720
>>> a += [1, 2, 3]
>>> a
[1, 2, 3]
>>> id(a) # This will still have the same ID as it did originally
4315491720
>>> a = a + [4, 5, 6]
>>> a
[1, 2, 3, 4, 5, 6]
>>> id(a) # Now it will have a different ID because of the assignment operation
4315489736
推荐阅读
- php - 在同一页面上读取和显示数据时无法解决错误“找不到对象”
- reactjs - 在 React 中下载和压缩文件?
- javascript - Pixi JS 老虎机游戏计数特定精灵
- android - 当用户单击 Kotlin 中的后退按钮时如何显示自定义对话框
- javascript - 在前端存储 AWS 凭证
- python-3.x - 在数据帧时间序列中标记价格的突然变化并为其着色
- c++ - 文件指针只读取第一个条目
- javascript - cdk-drop 不是已知元素
- java - SQLite 外键为空 AndroidStudio
- python - 循环遍历一个数据框中的单个列与另一个数据框中的列比较使用熊猫在第一个数据框中创建新列