赞
踩
众所周知,tuple与list的区别就是tuple是不可变的,是为了让程序更安全,tuple可以当作dict的key但是list不行。但tuple并不是完全不可变的,如下所示,tuple中的list的元素就是可以修改的。
- >>> a = 1
- >>> b = 2
- >>> c = [3,4,5]
- >>> d = (a,b,c)
- >>> d
- (1, 2, [3, 4, 5])
- >>> d[2][0]=9
- >>> d
- (1, 2, [9, 4, 5])
首先我们需要了解python中list的一些特性:
- >>> c
- [9, 4, 5]
- >>> c2 = c # 使用=定义一个新的list,实际上c2只是c的一个引用,修改c2中的元素,c也会同时被修改
- >>> c2
- [9, 4, 5]
- >>> c2[0]= 99
- >>> c
- [99, 4, 5]
- >>> id(c)
- 1868306709960
- >>> id(c2) # 发现c2和c的id是一样的,即二者的地址相同
- 1868306709960
- >>> c3 = [99, 4, 5] # 定义一个新的c3,元素组成与c2一样,不过此时虽然二者内容相等,但却是不同的list对象,占用的内存地址不同
- >>> c3 == c2 # == 只判断值是否相等
- True
- >>> c3 is c2 # is判断内存地址是否相同
- False
- >>> id(c3) # 发现c3的id与c2不同
- 1868306685576
-
- >>> id(c3[0]) # 查看c3里第一个元素的id
- 1885009424
- >>> c3[0]=999
- >>> id(c3[0]) # 修改c3[0]的值后,其id也随之改变,但是c3的地址不会发生改变
- 1868273844016
- >>> id(c3)
- 1868306685576
看完以上的代码,我们基本就能明白tuple中list中元素可变的原因:虽然list中的元素变了,但是list对象本身的内存地址并没有变,所以对tuple来说并没有元素发生变化。那么能否将list整体替换呢?理论上是不可行的,因为替换list本身会修改对象内存地址。看以下演示
- >>> d
- (1, 2, [99, 4, 5])
- >>> d[2] = 3 # 不可将list整体替换
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: 'tuple' object does not support item assignment
- >>> d[2]=c2 # 即使是将list整体替换成内存地址相同的对象也不可以,python直接不允许这种操作,以避免错误操作
- Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- TypeError: 'tuple' object does not support item assignment
c++里的参数传递允许传递引用和指针(所以C++难呀),而在python里,参数的传递是传递对象引用。
在python中,不可改变的对象有:str,int,float,tuple;可以改变的对象有list,dict,set。可变和不可变实际上指的是对象所占用的内存地址是否可变。下面以str和list演示可变和不可变的区别。
- >>> x = 'abc'
- >>> type(x)
- <class 'str'>
- >>> y = ['a', 'b', 'c']
- >>> type(y)
- <class 'list'>
- >>> x2 = 'abc' # 定义一个新的x2
- >>> y2 = ['a', 'b', 'c']
- >>> id(x), id(x2) # 比较两个内容相同的str的id,发现他们所占用的内存地址相同,
- (1868273892576, 1868273892576)
- >>> id(y), id(y2) # 比较两个内容相同的list的id,发现不同
- (1868306709832, 1868306709768)
-
- >>> x3 = x # 将x值赋给x3,此时二者占用的是同一个内存地址,相当于引用
- >>> x3
- 'abc'
- >>> x3 += 'd' # 修改x3时,由于x是str类型不可变,所以x并不会跟着变,x3此时实际上是调用了新的内存地址
- >>> x3
- 'abcd'
- >>> x
- 'abc'
- >>> y3 = y # 对于list正相反
- >>> y3
- ['a', 'b', 'c']
- >>> y3.append('d')
- >>> y3
- ['a', 'b', 'c', 'd']
- >>> y
- ['a', 'b', 'c', 'd']
- >>> y2
- ['a', 'b', 'c']
int和float类型和str一样,dict和list一样,不过tuple虽然是不可变的,但和str不完全一样:
- >>> n = (1,2,3)
- >>> m = (1,2,3)
- >>> id(n), id(m) # 虽然tuple是不可变的,但是内容相同的两个tuple地址是不一样的,这和list类似。
- (1868306704208, 1868306704424)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。