元组(tuple)
(1)创建元组
(2)元组的使用
(3)打包和拆包
(4)元组的操作
创建元组
-
表达式:(元组对象,…)
-
描述元组时,有时也可以不写对象(e.g. (1,2,3)与 1,2,3 表示的是同一个元组)
-
空元组:tuple() 或者 ()
-
用类型名tuple创建元组:tuple(可迭代对象)
e.g.>>>tuple(range(10)) (0,1,2,3,4,5,6,7,8,9) >>>tuple('abc') ('a','b','c')
-
元组一旦创建后,便不能改变。
-
只包含一个元素的元组,必须写一个逗号,括号不重要,系统显示元组时,总有括号。若不加逗号,只有括号,e.g.(12),解释器将认为这里出现的是普通括号,表示运算顺序的优先结合,并不表示元组。
e.g.>>>x = 1, >>>x (1,) >>>('abc',) ('abc',) #此时‘abc’字符串为元组的一个元素
-
元组可以取下标,但是不能通过下标给元组中的不可变元素重新赋值
e.g.>>>tup = ('a','b','c') >>>tup[0] 'a' >>>tup[0] = 'd' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
-
虽然元组本身不能改变,但是可以包含能改变的元素
e.g.>>>tup = (1,2,3,[1,2,3]) >>>tup[3][1] = 10 >>>tup (1,2,3,[1,10,3])
-
enumerate构造二元组的表,注意内置函数enumerate生成的是迭代器,并不真正生成结果的表,需要调用list得到表。
e.g.>>>seasons = ['Spring', ' Summer', 'Fall', 'Winter'] >>>enumerate(seasons) <enumerate object at 0x0000029D3B682990> >>>list(enumerate(seasons) [(0, 'Spring'), (1, ' Summer'), (2, 'Fall'), (3, 'Winter')]
调用enumerate函数得到元组的第一个元素下标为0,我们可以通过enumerate(seasons, start = 1)改变元素下标
e.g.>>>list(enumerate(seasons, start=1) [(1, 'Spring'), (2, ' Summer'), (3, 'Fall'), (4, 'Winter')]
元组的使用
元组是序列,因此也是可迭代对象。
- 元组可直接作为循环变量
e.g.
这里解释器会认为 in 后的是一个表达元组的表达式,可以加括号,也可以不加括号。>>> for x in 3.1, 4.0, 2.3, 5.5: print(x)
- 因为元组对象可以直接进行运算,因此任意表达式作为元组,也能使用 for 语句进行循环。
e.g.>>> for x in 3+1, sin(5), sqrt(4.7), 9.0: print(x)
打包和拆分
python支持打包(packing)和拆分(unpacking)的隐式动作
-
赋值中的打包和拆分
打包
e.g.>>> tp = 123,345,'and',567 #创建元租就是打包
即将对象123,345,‘and’,567打包成一个元组,做成一个整体的对象,赋值给 tp。
拆分
e.g.>>> a,b,c,d = tp
tp 由之前定义为(123,345,‘and’,567)四个元素的元组,给a,b,c,d赋值时解释器自动将元组拆开,把其中的元素分别按位置赋给四个变量,此时a,b,c,d的值为:
>>>a 123 >>>b 345 >>>c 'and' >>>d 567
要完成这种赋值,等号两边的变量个数必须正好相等,否则会报错
e.g.>>>tp = [1,2,3,4,5] >>>a,b,c,d = tp Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: too many values to unpack (expected 4)
其实,各种序列都可以拆分,只要满足赋值语句两边的元素结构相同
e.g.>>> a,b,d = [1,2,3] #列表的拆分 >>> a,[b,c] = [1,(2,3)] #两层拆分 >>>a,(b,c),d = [1,(2,3),4]
-
函数的参数与元组
区分函数中的简单实参表达式和元组实参函数 实参意义 f1(a,b,c+1) 三个实参调用函数f1 f2((a,b,c+1)) 一个元组实参调用函数f2 f3(a,(b,c+1)) 两个实参调用函数f3,一个是简单实参a,另一个是元组, f4(2,3,) 两个实参调用函数f4,3后面的逗号被忽略,没有影响 f5(2,(3,)) 两个实参调用函数f5,一个是简单实参2,另一个是单元组 f6(2,(3)) ; f7(2,(x+1)) f6,f7都调用了两个实参,括号没有实际作用 带星号形参
-
在函数定义中,除了可以有前面介绍多的普通形参(可以带默认值)之外,还可以有一种能接受任意多个实参的形参。
-
形式:*形参名 (即在形参名前加一个星号)
-
其值为一些实参的元组。
-
在一个函数定义的参数表里只能有一个这样的形参
-
在函数调用时,带星号形参将约束到所有未能得到匹配的普通实参构成的元组,默认情况是约束到空元组(如果函数调用中没有未匹配的实参)
e.g.def mysum(*args): s = 0 for x in args: s += x reruen s
调用函数
>>>print(mysum(1,2,3,4,5,6) 21 >>>print(mysum()) 0
注意:若函数形参表里的某个普通形参带有默认值,(即a=1的形式),位于其后直至带星号形参的所有普通形参都必须带默认值。若带星号形参后还有普通形参,函数调用时,必须用关键字实参的形式为他们提供实参。
e.g.>>>def f(a,b=3,c,*args): #将会报 SyntaxError >>>def f(a,b=3,c=4,*args): #允许 >>>def g(a,b=3,c=4,*args,d): >>>print(g(........,e=1)) #调用函数g时必须用关键字实参的形式给e提供实参,否则会报错
- 普通实参按位置与形参一一匹配
- 关键字实参按关键字与同名实参匹配
- 没得到实参但有默认值的形参取其默认值为实参
- 前面匹配剩下的普通实参做成一个元组约束到带星号形
拆分实参
在实参表达式前加*,表达式应为一个可迭代对象(表或者元组),来表示实参对象。解释器会将这个对象拆分,用其元素为函数提供若干个实际的实参。
调用前面定义的mysum函数进行解释:>>> a = 1,2,3,4,5,6 >>>print(mysum(*a)) 21
也可用于为多个循环统一描述对象:
>>> b = [0,20,3] >>> for i in range(*b): #等同于for i in range(0,20,3)
-
元组的操作
序列 | 表达式 | 意义 |
---|---|---|
1 | s.count(x) | x在s中出现的次数 |
2 | s.index(x[,i[,j]] | x在s中首次出现的下标 |
3 | max(s) ; min(s) | s中的最大元素;s中的最小元素 |
4 | len(s) | s的长度 |