python数据类型之谜--tuple

数据类型 – tuple

众所周知,在python中有6种常见的基本数据类型

  • 三种可变得数据类型:列表(list)、集合(set)、字典(dict);
  • 三种不可变的数据类型:数值类型(int/flaot)、字符串类型(str)、元组(tuple)

其中对于可变和不可变的数据类型相信每一个人都知道是指的是其中的元素是否可以改变,改变其中的值元素对象的地址是否改变。

那么接下来,我们就来讨论一下今天的主角–tuple,他真的是不可变的嘛?

废话不多说,直接上代码

"""
我相信以下的代码所有人都明白,因为list本来就是可变的嘛,改变自身的元素,其在内存中的地址不会改变,这是必然的
"""

# 定义一个可变数据类型列表
my_list = [1,2,3,4,5,6]
print(my_list)
# 打印其在内存中的地址
print(id(my_list))
# 修改其中的值并再次打印地址
my_list[1] = "Hello World!"
print(my_list)
print(id(my_list))


"""
[1, 2, 3, 4, 5, 6]
139625990619336
[1, 'Hello World!', 3, 4, 5, 6]
139625990619336
"""

那么我们接下来看下面一段代码,当然下面是一段错误的代码,相信很多人也发现错误了,因为元组是不可以改变的

# 定义一个不可变对象元素
tuple_test = (1,2,3,4,5,6,7,8)
print(tuple_test)
print(id(tuple_test))
# 按照列表的方式去修改其中的值
tuple_test[1] = 0
print(tuple_test)
print(id(tuple_test))

"""
140436881404760
Traceback (most recent call last):
  File "/home/mr_liang/PycharmProjects/python_arithmetic/Test/tuple_test.py", line 6, in <module>
    tuple_test[1] = 0
TypeError: 'tuple' object does not support item assignment
"""

看过了上面的一段更改元组出现错误的代码,元组是不是真的不可变呢?继续往下看

# 定义一个不可变对象元素
tuple_test = (1,2,3,4,[11,22,33])
print(tuple_test)

# 按照列表的方式去修改其中的值
tuple_test[4][1] = "hello world!"
print(tuple_test)

"""
(1, 2, 3, 4, [11, 22, 33])
(1, 2, 3, 4, [11, 'hello world!', 33])
"""

谁说元祖是不可变的,上面的代码不就是改变了元组的值了嘛?难道是书上讲的有问题或者老师讲的有问题嘛?


画重点,敲黑板

我们接下来来解答你们的疑问?????

首先我们把上述的代码进行解析:

"""
一下两步操作,我们主要的工作是定义了一个不可变对象tuple,并将其值打印在控制台,并且记录地址
"""
# 定义一个不可变对象元素
tuple_test = (1,2,3,4,[11,22,33])
print(tuple_test)
old_id = id(tuple_test)

"""
接下来我们做了一个神奇的操作,我们对元组中的值进行了修改,并再次打印,并且记录地址
"""
# 按照列表的方式去修改其中的值
tuple_test[4][1] = "hello world!"
print(tuple_test)
new_id = id(tuple_test)

"""
现在我们在来进行一步操作打印元素的地址
"""
print("old id : ", old_id)
print("new id : ", new_id)


"""
(1, 2, 3, 4, [11, 22, 33])
(1, 2, 3, 4, [11, 'hello world!', 33])
old id :  139994371137960
new id :  139994371137960
"""

咦,你是不是发现了什么问题,元组中的值改变了,但是元组的地址为什么没有改变了,不是说元组中的不可变嘛?

实际上,元组中的值是确实不可改变的,我们上述改变了元组的值吗?实际上并没有,我们看到在元组中我们存储了一个list列表,并且对其中的值进行了修改,我们看到的是对元组的修改,但是实际上却并不是这样的,实际在存储的过程中,元组中存储的知识一个list列表的引用,我们队元组中的list进行修改,因为list本来就是可变的,所以在元组中存储的list列表的引用并不会发生改变,我们每一次输出元组的值得时候,元组拿到那个列表的引用的时候回去内存中找到那个引用地址所对应的数据,输出在控制台上,所以说,我们看见的元组的值发生改变并不是这样喔,元组中的值并没有发生改变,下面举列子说明:

# 定义一个不可变对象元素,其中这个对象存储了一个nums对象
nums = [11,22,33]
tuple_test = (1,2,3,4,nums)
old_id = id(tuple_test)

# 我们队nums进行了修改
nums[1] = "hello world!"
print(tuple_test)
new_id = id(tuple_test)

print("old id : ", old_id)
print("new id : ", new_id)

"""
(1, 2, 3, 4, [11, 22, 33])
(1, 2, 3, 4, [11, 'hello world!', 33])
old id :  139997236286656
new id :  139997236286656

解析:
	实际上我们的元组中在内存中存储的相当于是tuple_test = (id(1),id(2),id(3),id(4),id(nums)),
	这样我们每次获取到的都是一个内存地址,当我们去操作内存地址的时候,内存地址指向的那个数据是变类型,
	修改该数据的数据,该数据所对应的地址是没有发生改变的喔,其中set、dict如果放在元组中也是一样的道理,
	实际上元组中的值是没有改变的喔
"""

现在我相信应该所有人都明白了吧,元组中的数据类型的的确确是不可以改变的喔

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值