前面的两节课,咱们为咱们解说了 Python 中的列表,它是一种容器型的数据类型,经过列表类型的变量,咱们能够保存多个数据并经过循环实现对数据的批量操作。当然,Python 中还有其他容器型的数据类型,接下来咱们就为咱们解说另一种容器型的数据类型,它的名字叫元组(tuple)。
元组的界说和运算
在 Python 中,元组也是多个元素依照必定次序构成的序列。元组和列表的不同之处在于,元组是不可变类型,这就意味着元组类型的变量一旦界说,其间的元素不能再增加或删除,并且元素的值也不能修正。假如企图修正元组中的元素,将引发TypeError
错误,导致程序溃散。界说元组一般运用形如(x, y, z)
的字面量语法,元组类型支撑的运算符跟列表是一样的,咱们能够看看下面的代码。
# 界说一个三元组
t1 = (35, 12, 98)
# 界说一个四元组
t2 = ('骆昊', 43, True, '四川成都')
# 查看变量的类型
print(type(t1)) # <class 'tuple'>
print(type(t2)) # <class 'tuple'>
# 查看元组中元素的数量
print(len(t1)) # 3
print(len(t2)) # 4
# 索引运算
print(t1[0]) # 35
print(t1[2]) # 98
print(t2[-1]) # 四川成都
# 切片运算
print(t2[:2]) # ('骆昊', 43)
print(t2[::3]) # ('骆昊', '四川成都')
# 循环遍历元组中的元素
for elem in t1:
print(elem)
# 成员运算
print(12 in t1) # True
print(99 in t1) # False
print('Hao' not in t2) # False
# 拼接运算
t3 = t1 + t2
print(t3) # (35, 12, 98, '骆昊', 43, True, '四川成都')
# 比较运算
print(t1 == t3) # False
print(t1 >= t3) # False
print(t1 <= (35, 11, 99)) # False
一个元组中假如有两个元素,咱们就称之为二元组;一个元组中假如五个元素,咱们就称之为五元组。需求提醒咱们留意的是,()
表示空元组,可是假如元组中只有一个元素,需求加上一个逗号,否则()
就不是代表元组的字面量语法,而是改变运算优先级的圆括号,所以('hello', )
和(100, )
才是一元组,而('hello')
和(100)
仅仅字符串和整数。咱们能够经过下面的代码来加以验证。
a = ()
print(type(a)) # <class 'tuple'>
b = ('hello')
print(type(b)) # <class 'str'>
c = (100)
print(type(c)) # <class 'int'>
d = ('hello', )
print(type(d)) # <class 'tuple'>
e = (100, )
print(type(e)) # <class 'tuple'>
打包和解包操作
当咱们把多个用逗号分隔的值赋给一个变量时,多个值会打包成一个元组类型;当咱们把一个元组赋值给多个变量时,元组会解包成多个值然后别离赋给对应的变量,如下面的代码所示。
# 打包操作
a = 1, 10, 100
print(type(a)) # <class 'tuple'>
print(a) # (1, 10, 100)
# 解包操作
i, j, k = a
print(i, j, k) # 1 10 100
在解包时,假如解包出来的元素个数和变量个数不对应,会引发ValueError
反常,错误信息为:too many values to unpack
(解包的值太多)或not enough values to unpack
(解包的值缺乏)。
a = 1, 10, 100, 1000
# i, j, k = a # ValueError: too many values to unpack (expected 3)
# i, j, k, l, m, n = a # ValueError: not enough values to unpack (expected 6, got 4)
有一种处理变量个数少于元素的个数办法,便是运用星号表达式。经过星号表达式,咱们能够让一个变量接收多个值,代码如下所示。需求留意两点:首先,用星号表达式润饰的变量会变成一个列表,列表中有0个或多个元素;其次,在解包语法中,星号表达式只能呈现一次。
a = 1, 10, 100, 1000
i, j, *k = a
print(i, j, k) # 1 10 [100, 1000]
i, *j, k = a
print(i, j, k) # 1 [10, 100] 1000
*i, j, k = a
print(i, j, k) # [1, 10] 100 1000
*i, j = a
print(i, j) # [1, 10, 100] 1000
i, *j = a
print(i, j) # 1 [10, 100, 1000]
i, j, k, *l = a
print(i, j, k, l) # 1 10 100 [1000]
i, j, k, l, *m = a
print(i, j, k, l, m) # 1 10 100 1000 []
需求阐明一点,解包语法对所有的序列都建立,这就意味着咱们之前讲的列表、range
函数构造的范围序列乃至字符串都能够运用解包语法。咱们能够尝试运行下面的代码,看看会呈现怎样的结果。
a, b, *c = range(1, 10)
print(a, b, c)
a, b, c = [1, 10, 100]
print(a, b, c)
a, *b, c = 'hello'
print(a, b, c)
交流变量的值
交流变量的值是写代码时经常用到的一个操作,可是在许多编程语言中,交流两个变量的值都需求借助一个中心变量才能做到,假如不必中心变量就需求运用比较晦涩的位运算来实现。在 Python 中,交流两个变量a
和b
的值只需求运用如下所示的代码。
a, b = b, a
同理,假如要将三个变量a
、b
、c
的值交流,即b
的值赋给a
,c
的值赋给b
,a
的值赋给c
,也能够如法炮制。
a, b, c = b, c, a
需求阐明的是,上面的操作并没有用到打包和解包语法,Python 的字节码指令中有ROT_TWO
和ROT_THREE
这样的指令能够直接实现这个操作,功率是非常高的。可是假如有多于三个变量的值要依次交流,这个时分是没有直接可用的字节码指令的,需求经过打包解包的方式来完结变量之间值的交流。
元组和列表的比较
这里还有一个非常值得探讨的问题,Python 中已经有了列表类型,为什么还需求元组这样的类型呢?这个问题对于初学者来说似乎有点困难,不过没有关系,咱们先抛出观念,咱们能够一边学习一边慢慢领会。
-
元组是不可变类型,不可变类型更适合多线程环境,由于它降低了并发访问变量的同步化开销。关于这一点,咱们会在后面解说并发编程的时分跟咱们一同探讨。
-
元组是不可变类型,一般不可变类型在创立时刻上优于对应的可变类型。咱们能够运用
timeit
模块的timeit
函数来看看创立保存相同元素的元组和列表各自花费的时刻,timeit
函数的number
参数表示代码履行的次数。下面的代码中,咱们别离创立了保存1
到9
的整数的列表和元组,每个操作履行10000000
次,计算运行时刻。import timeit print('%.3f 秒' % timeit.timeit('[1, 2, 3, 4, 5, 6, 7, 8, 9]', number=10000000)) print('%.3f 秒' % timeit.timeit('(1, 2, 3, 4, 5, 6, 7, 8, 9)', number=10000000))
输出:
0.635 秒 0.078 秒
阐明:上面代码的履行结果因软硬件系统而异,在我现在运用的电脑上,履行
10000000
次创立列表的操作时刻是0.635
秒,而履行10000000
次创立元组的操作时刻是0.078
秒,明显创立元组更快且二者时刻上有数量级的不同。咱们能够在自己的电脑上履行这段代码,把你的履行结果放到谈论区,看看谁的电脑装备更厉害。
当然,Python 中的元组和列表类型是能够彼此转换的,咱们能够经过下面的代码来完结该操作。
infos = ('骆昊', 43, True, '四川成都')
# 将元组转换成列表
print(list(infos)) # ['骆昊', 43, True, '四川成都']
frts = ['apple', 'banana', 'orange']
# 将列表转换成元组
print(tuple(frts)) # ('apple', 'banana', 'orange')
总结
列表和元组都是容器型的数据类型,即一个变量能够保存多个数据,并且它们都是按必定次序组织元素的有序容器。列表是可变数据类型,元组是不可变数据类型,所以列表能够增加元素、删除元素、清空元素、排序反转,但这些操刁难元组来说是不建立的。列表和元组都能够支撑拼接运算、成员运算、索引运算、切片运算等操作,后面咱们要讲到的字符串类型也支撑这些运算,由于字符串便是字符按必定次序构成的序列,在这一点上三者并没有什么区别。咱们推荐咱们运用列表的生成式语法来创立列表,它不只好用并且功率很高,是 Python 语言中非常有特色的语法。