7.3 元组
7.3.1 元组的基本概念
元组是类似于列表的数据类型,也是元素的有序集合,元素可以根据下标来查看。
元组和列表最大的区别是:元组不可修改。
元组的概念元组表示形式如下:
(元素0,元素 1,元素2......)
有时括号也可以省去。
t = (12,) #只有一个元素的元组,后面需要加,
print(t)
t2 = (12) #只有一个元素时,后面不加, 只是将变量值赋给t2
print(t2)
t3 = (12,13)
print(t3)
t4 = 12345, 54321, 'hello!' #t 是一个三元素的元组,这种情况不加()也可以识别为元组
print("t4:",t4)
print("t4[0]:",t4[0])
u = t4, (1, 2, 3, 4, 5) #u有两个元素,两个元素都是元组
print("u:",u)
print("u[0]:",u[0]) #取出u元组下标为0的元素,即(12345, 54321, 'hello!')
print("u[0][1]):",u[0][1]) #取出u[0]元素,此元素为一个元组,再取出该元组下标为1的元素54321
t4[0] = 8888 #报错,元组的元素不可修改
print(t4)
第1行: (12)表示一个元组,里面只有一个元素12。(12)则不是元组,就表示整数12。想表示单元素元组,要在元素后面加","。
第2行:对t重新赋值,就是让变量t指向别处而已,并没有和“元组不可修改”的说法矛盾。
第3行:有的情况下表示元组的时候,括号可以去掉。
第6行: u是有两个元素的元组。这两个元素都是元组,分别是t和(1,2,3,4,5)。
第8行: u[0][1] 表示u[0]的下标为1的元素,那就是[1]。
和列表一样,元组的元素也是指针,但是这个指针只能指向固定的地方,不能修改指向。换句话说,就是不可对元组的元素赋值。
正如上面第10行所示。说元组不可修改,准确地说是指元组不支持以下操作。
(1)对元组的元素进行赋值。
(2)对元组添加元素,或者删除元素。
(3)改变元组元素的顺序,例如对元组排序。许多教材和网上资料提到“元组元素不能修改”,这个说法不准确,或者含义不明。准确的说法是元组的元素不能被赋值。
元组的元素是指针,该指针指向的内容并非不可被修改。
例如,如果元组的元素是个列表(或字典、集合),那么这个列表(或字典、集合)是可以被修改的:
v = ("hello",[1, 2, 31, [3, 2, 1]])
#v[1] = 32 #运行错误,元组元素不可修改成指向别处
v[1][0] = 'world' #v [1]指向的内容可以被修改
print(v)
print(len(v))
t = [1, 2]
v = (t, t)
print(v)
t[0] = 'ok'
print(v)
t = 8
print(v)
第1行:元组v的元素v[1]和v[2]都是列表。
第2行:试图对元组的元素进行赋值,这是不允许的。
第3行: v[1]是个指针,指向列表[1,2,3]。
可以修改v[1]指向的内容,即将列表[1, 2, 3]中的1改成了'world'。因此第4行输出v可以看到v[1]的内容变成了['world, 2, 3]。
对v1进行赋值,并不是对元组 v 的元素赋值。只有对 v[0],v[1],v[2]......进行赋值,才算是对元组元素进行赋值。
第7行:元组v的两个元素都和t指向相同的地方。若t指向的内容发生了变化,正如第9行所做的,那么v的内容自然也会发生变化,正如第10行输出结果所示。
第11行:让t指向别处,自然不会影响到v,正如第12行输出v结果所示。
打个比方,所谓的元组不可修改,类似于组建了一支球队,规定球队建好后不可换人,不可加人,不可减人,不可修改队员号码。但是队员换个发型,增加体重,受伤缺胳膊少腿,甚至长出三头六臂,都是可以的。
有的函数,看上去像返回了多个值,实际上是返回了一个元组,例如:
def sumAndDifference(x,y):
return x + y,x - y #等价于return(x+y,x-y),返回元组
s = sumAndDifference(10,5)
print(s)
运行结果,发现是一个元组
第三行也可以写成(s, d) = sumAndDifference(10, 5)。
原理:在 Python 中,当在一个函数中使用多个值作为返回结果且没有用特定的数据结构包裹它们时,Python 会自动将这些值组合成一个元组进行返回。
7.3.2 元组的操作
元组和字符串一样,有切片的操作,操作方法也基本相同。
-
元组的切片也是元组。
-
元组可以用“+”连接。
-
用in和 not in可以判断元素是否在元组里面。
-
两个元组还可以比大小。
-
元组可以和整数相乘。
-
元组可以用for循环遍历。
tup2 = (1, 2, 3, 4, 5, 6, 7 )
print(tup2[1:5])
print(tup2[::-1])
print(tup2[-1:0:-2])
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
tup3 = tup1 + tup2
print (tup3) #>>(12, 34.56, 'abc', 'xyz')
tup3 += (10,20)
print(tup3) #>>(12, 34.56, 'abc', 'xyz',10,20)
print((1,2,3) * 3)
print( 3 in (1,2,3))
for i in (1,2,3):
print(i,end = "")
需要注意的是,第9行并不是在tup3尾巴直接添加10和20两个元素。它的效果是新生成一个元组tup3+(10,20),然后把新元组赋值给tup3。
元组可以比大小,可以用“==”和"!=”判断是否相等。
两个元组a和b比大小,就是逐个元素比大小,直到分出胜负。如果a的最后一个元素都比完了还胜负未分,且b比a长,则a比b小。如果有两个对应元素不可比大小,则产生运行时错误。
例如:
print((1, 'a', 12) < (1, 'b', 7))
print((1, 'a') < (1, 'a', 13))
print((2,'a')> (1,'b',13))
print((2, 'a') < ('ab', 'b', 13))
第4行,因2和'ab'不能比大小,于是导致程序出错。
有时元组可以用来取代复杂的分支结构。
例如输入1~7,相应输出星期一到星期天,这个问题如果用if..elif语句解决,就要写很多个elif,不太方便。用上元组,可以不写if语句:
weekdays = "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"
n = int(input("请输入数字1-7,会输出对应的星期几:"))
if n > 7 or n < 1: #n的取值:1-7
print ("输入错误")
else:
print (weekdays[n-1]) #通过下标取元组weekdays中的元素