今天分享一道 Python 题目,可能会让你涨点知识。
题目:以下代码的输出结果是什么?
>>> crazy_tuple = (["x","y"],) >>> crazy_tuple[0] = crazy_tuple[0].__iadd__(["z"]) >>> print(crazy_tuple[0]) ???
选项:
- A) ["x", "y"]
- B) ["x", "y", "z"]
- C) 会抛出 TypeError 异常
- D) 有没有搞错?
先铺垫一个小知识,列表的魔法函数 __iadd__ 相当于列表的 extend 函数,但是会返回扩展后的结果:
>>> [1,2,3].__iadd__([4]) [1, 2, 3, 4]
接下来你会选择哪个选项呢?
等你 30 秒。
接下来在 Python 解释器上运行一下,看看是否符合你的预期:
>>> crazy_tuple = (["x","y"],) >>> crazy_tuple[0] = crazy_tuple[0].__iadd__(["z"]) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> print(crazy_tuple[0]) ['x', 'y', 'z'] >>>
会发现,第二行代码抛出了 TypeError 异常,告诉我们,元组不支持元素赋值,此时,你会选择 C,但是打印第一个元素(列表)时发现列表添加了 'z',你又选择了 B。
你又想了想,Python 是不是搞错了,既然你不支持元组内的元素重新赋值,还让它赋值了,是不是搞错了,你想选择 D。
所以这很 crazy !
现在来一起梳理一下。
首先,crazy_tuple 是一个元组,元组不可变,是指元组内元素的地址永不改变:
>>> crazy_tuple = (["x","y"],) >>> id(crazy_tuple[0]) 140468737595456
凡是对列表内的元素使用 = 操作符号的,均抛出 TypeError 异常
>>> id(crazy_tuple[0]) 140468737595456 >>> crazy_tuple[0] = object() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> id(crazy_tuple[0]) 140468737595456 >>> crazy_tuple[0] ['x', 'y'] >>>
虽然抛出了异常,但是地址仍然不变。
我们执行的代码是 crazy_tuple[0] = crazy_tuple[0].__iadd__(["z"]),Python 解释器先执行的是等号右边的部分 crazy_tuple[0].__iadd__(["z"])
我们可以这样分解它的执行过程:
tmp = crazy_tuple[0].__iadd__(["z"]) crazy_tuple[0] = tmp
在解释器执行一下:
>>> tmp = crazy_tuple[0].__iadd__(["z"]) >>> crazy_tuple[0] ['x', 'y', 'z'] >>> id(crazy_tuple[0]) 140468737595456 >>> crazy_tuple[0] = tmp Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment >>> tmp = crazy_tuple[0].__iadd__(["z"]) crazy_tuple[0] = tmp
可以看出, crazy_tuple[0].__iadd__(["z"]) 执行之后,crazy_tuple[0] 的内容已经发生了变化,但地址不变。
因此,你虽然看到了报错,但是修改的结果还是发生了。
总结:元组的不可变,在于元组内元素的地址不可变。如果元组内元素是字符串、数字、元组等不可变对象,其内容永久不变,如果元组内元素是是列表、字典、集合等可变对象,其内容可以被改变。
以上就是“Python疯狂的元组”的详细内容,想要了解更多关于Python教程欢迎持续关注编程学习网
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/9933/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料