python:一些关于元组的碎碎念

初始化元组的时候,尤其是元组里面只有一个元素的时候,会出现一些很蛋疼的情况:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__=="__main__":
 tuple1 = (1)#坑爹的初始化,这个写法初始化出来是个int!!!
 checkContentAndType(tuple1)
 tuple1 = (1,)#
 checkContentAndType(tuple1)
 list1 = [1]
 checkContentAndType(list1)
 set1 = {1}
 checkContentAndType(set1)
 dict1 = {1: 1}
 checkContentAndType(dict1)

运行结果是:

1
<class 'int'>
(1,)
<class 'tuple'>
[1]
<class 'list'>
{1}
<class 'set'>
{1: 1}
<class 'dict'>
Process finished with exit code 0

第一个初始化出来的居然是个int!,真坑,所以元组里面至少要有一个逗号这个奇怪的经验就出现了

然而,初始化时候还有什么骚操作呢?看这个:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__=="__main__":
 tupleTest=1,2,3,'4',5
 checkContentAndType(tupleTest)

他得到的居然还是一个元组!!!没有括号也可以成为元组啊!(嗯,不能自动成为list,也不能成为set,dict也不行,就是tuple)

(1, 2, 3, '4', 5)
<class 'tuple'>

于是我们想,python解包原理可以给多个变量同时赋值,看看会发生什么?

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__=="__main__":
 tupleTest1,tupleTest2=1,2,3,'4',5
Traceback (most recent call last):
 File "C:/Users/avatu/PycharmProjects/play/坑爹的初始化.py", line 6, in <module>
 tupleTest1,tupleTest2=1,2,3,'4',5
ValueError: too many values to unpack (expected 2)
Process finished with exit code 1

emmmmm,果然,不能这样做,稍微修改一下:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__=="__main__":
 tupleTest1,tupleTest2=1,(2,3,'4',5)
 checkContentAndType(tupleTest1)
 checkContentAndType(tupleTest2)
1
<class 'int'>
(2, 3, '4', 5)
<class 'tuple'>
Process finished with exit code 0

和之前的经验不冲突,第一个果然还是变成了个int,后面的成功分配给第二个标识符,成为了一个元组......

再改一改:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__=="__main__":
 tupleTest1,tupleTest2=(1,2,3),('4',5)
 checkContentAndType(tupleTest1)
 checkContentAndType(tupleTest2)
(1, 2, 3)
<class 'tuple'>
('4', 5)
<class 'tuple'>
Process finished with exit code 0

emmmmm,没被毛病,按照预计运行了.很好...!

关于很多书上都说,元组的元素不能修改。

我们来看一个诡异的例子:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__ == "__main__":
 tuple1 = ([1], 2, 'str-1', 'str-2')
 for i in range(len(tuple1)):
 if i == 0:
 tuple1[i].append('Pep8 is fun')
 print(tuple1[i])

结果:

[1, 'Pep8 is fun']
2
str-1
str-2
Process finished with exit code 0

哎呦,我去,怎么改了????

然而,真的改了吗?...再看下面例子:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__ == "__main__":
 tuple1 = ([1], 2, 'str-1', 'str-2')
 for i in range(len(tuple1)):
 if i == 0:
 # tuple1[i].append('Pep8 is fun')
 tuple1[i]=[1,'Pep8 is fun']
 print(tuple1[i])

结果:

Traceback (most recent call last):
 File "C:/Users/avatu/PycharmProjects/play/坑爹的初始化.py", line 11, in <module>
 tuple1[i]=[1,'Pep8 is fun']
TypeError: 'tuple' object does not support item assignment
Process finished with exit code 1

嗯?怎么append()可以,赋值就不行了呢?

其实很简单.我们说python是完全面向对象的语言,那么一个int,一个list,都是一个对象,元组里面并不是把对象本身给塞进去了,而是把对象的指针给塞进去了!!!

看完下面这个例子就明了啦:

def checkIdAndValue(obj):
 print(id(obj))
 print(obj)
if __name__ == '__main__':
 list1 = [1, 2, 3]
 checkIdAndValue(list1)
 list1.append(4)
 checkIdAndValue(list1)

结果:

2603360595784
[1, 2, 3]
2603360595784
[1, 2, 3, 4]
Process finished with exit code 0

你看,append()并没有改变原有list的id()...也就是说,地址没变啊!想想C语言....数据结构的首地址 bla bla bla......

再看等号:

def checkIdAndValue(obj):
 print(id(obj))
 print(obj)
if __name__ == '__main__':
 list1 = [1, 2, 3]
 checkIdAndValue(list1)
 list1.append(4)
 checkIdAndValue(list1)
 list1 = [1, 2, 3, 4]
 checkIdAndValue(list1)

结果:

2596211797832
[1, 2, 3]
2596211797832
[1, 2, 3, 4]
2596211888584
[1, 2, 3, 4]
Process finished with exit code 0

对象的id发生变化了啊!

这样,就明白了,元组里面元素"可以被改变"的表象下,深层的原理:锁定的是一个指向对象的地址,但不是锁定了这个对象.

同样的原理:

def checkContentAndType(obj):
 print(obj)
 print(type(obj))
if __name__ == "__main__":
 tuple1 = ([1], {2, 3},{4:5, 6:7}, 'str-1', 'str-2')
 for i in range(len(tuple1)):
 if i == 0:
 tuple1[i].append('Pep8 is fun')
 elif i == 1:
 tuple1[i].add('Pep8 is fun')
 elif i == 2:
 tuple1[i][8] = 9 #K-V操作
 print(tuple1[i])

结果:

[1, 'Pep8 is fun']
{2, 3, 'Pep8 is fun'}
{4: 5, 6: 7, 8: 9}
str-1
str-2
Process finished with exit code 0

凡是这种修改后不造成id()变化的操作,都能从表面上去改变一个元组.

你看,以前学的值引用和址引用的知识用上了吧? 哈哈

python:一些关于元组的碎碎念

相关推荐