打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
写了这么多年 Python,Tuple 竟然是可变的?

关键时刻,第一时间送达!

作者 | 猿媛牧场

责编 | 唐小引

1

根据 Python 对数据类型的定义:“objects are Python's abstraction for data, and all data in a Python program is represented by objects or by relations between objects”。

Python 中一切皆对象,包括整数,浮点数和布尔值。在 Java 中,这些是“primitive 数据类型”,并被视为与“objects”分开。

在 Python 中并非如此。Python 中的每个值都是一个对象,所以不仅 datetime.datetime(2018, 6, 3, 19, 38, 54, 798338)datetime 对象是一个对象,而且整数 69 是一个对象,布尔 True 是一个对象。

所有的 Python 对象都有三件事:一个值,一个类型和一个身份。这有点令人困惑,因为我们经常随便说,例如“值 69”。

>>> spam = 69
>>> spam
69
>>> type(spam)
class 'int'>
>>> id(spam)
4307168128

该变量 spam 指的是具有值 69,类型 int 和 id 为 4307168128。id 是一个唯一的整数,在创建对象时创建,并且永远不会改变对象的生命周期。对象的类型也不能改变。只有对象的值可能会改变。

让我们尝试通过在交互式 Shell 中输入以下内容来更改对象的值:

>>> spam = 69
>>> spam = 666

可能有的同学就会认为已经将对象的值从 69 改变为 666,然而并没有。我们所做的都是将 spam 指向 1 个新的对象。

>>> spam = 69
>>> id(spam)
4307168128
>>> spam = 666
>>> id(spam)
4325801680

整数(浮点数,布尔值,字符串,字节)是不可变的。另外,列表(字典,集合,数组和字节数组)是可变的。这可能会导致一个常见的 Python 陷阱:

>>> spam = ['miracle', 'young']
>>> papapa = spam
>>> spam
['miracle', 'young']
>>> papapa
['miracle', 'young']
>>> spam.append('girl')
>>> spam
['miracle', 'young', 'girl']
>>> papapa
['miracle', 'young', 'girl']

究其原因就是 papapa 和 spam 同时指向了同一个对象。来看 papapa = spam 这行。创建了引用的副本,而不是对象。

2

关于 Python is 和 == 的区别,以后我会单独拿出来说一下的。

这里我们先来看几个例子:

>>> id(spam) == id(papapa)
True
>>> spam is papapa
True
>>> spam == papapa
True
>>> fxxk = ['miracle', 'young', 'girl']
>>> spam == fxxk
True
>>> id(fxxk)
4325976648
>>> spam is fxxk
False
>>> id(spam)
4325974216

2 个不同的变量,他们可以共享同一个值,但是永远无法共享同一个对象。

3

好了,现在有了上面这些做铺垫,我们终于可以展开 tuple 到底是 mutable or immutable 了。

从某种意义上说,元组是不可变的,因为元组中的对象不能被删除或被新对象所替代。就像 spam=69;spam=666 不改变 spam=69 中的对象一样; 它用一个全新的对象代替它,666。

>>> spam = ['miracle', 'young', ['girl', 'boy']]
>>> spam = ('miracle', 'young', ['girl', 'boy'])
>>> id(spam[0]), id(spam[1]), id(spam[2])
(4325825872, 4327743416, 4326146632)

相同的对象将始终存在于这个元组中,并且它们将始终具有相同顺序的相同身份:4325825872 和 4327743416. 因为元组是不可变的。

然而在另一种意义上,元组是可变的,因为它们的值可以被改变。

>>> fxxk = ('miracle', 'young', ['girl', 'boy'])
>>> spam == fxxk
True
>>> spam is fxxk
False
>>> spam[2].append('man')
>>> spam == fxxk
False

在这个例子中,元组称为通过 spam 和 fxxk 具有相等的值(根据==),但是是不同的对象(根据 is)。

接着我们改变了 spam 的值,因为 spam 不再等于 fxxk,而我们也没有改变 fxxk 的值。所以元组又是可变的。

声明:本文为作者投稿,版权归作者所有。

  征稿啦!

CSDN 公众号秉持着「与千万技术人共成长」理念,不仅以「极客头条」、「畅言」栏目在第一时间以技术人的独特视角描述技术人关心的行业焦点事件,更有「技术头条」专栏,深度解读行业内的热门技术与场景应用,让所有的开发者紧跟技术潮流,保持警醒的技术嗅觉,对行业趋势、技术有更为全面的认知。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
给妹子讲python-S01E20函数参数的传递与修改
Python3 自学第6天:元组tuple
Python编程基础:序列类型概述
刚刚,Python 3.10 正式发布了!我发现了一个可怕的功能...
Python不同数据类型的区别是什么?
[快学Python3]函数
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服