1、创建元组
Python 的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号 ( ),列表使用方括号 [ ]。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
创建元组的例子
>>> tup1 = ('Google', 'Runoob', 1997, 2000)
>>> tup2 = (1, 2, 3, 4, 5 )
>>> tup3 = "a", "b", "c", "d" # 不需要括号也可以,最好还是加上小括号()
>>> type(tup3)
<class 'tuple'>
创建空元组
tup1 = ()
元组中只包含一个元素时,需要在元素后面添加逗号 , ,否则括号会被当作运算符使用:
>>> tup1 = (50)
>>> type(tup1) # 不加逗号,类型为整型
<class 'int'>
>>> tup1 = (50,)
>>> type(tup1) # 加上逗号,类型为元组
<class 'tuple'>
2、访问元组
元组与字符串类似,下标索引从 0 开始,可以进行截取,组合等。
正向索引
>>> tup = ('red', 'green', 'blue', 'yellow', 'white', 'black')
>>> tup[0]
'red'
>>> tup[2]
'blue'
>>> tup[5]
'black'
>>>
反向索引
>>> tup = ('red', 'green', 'blue', 'yellow', 'white', 'black')
>>> tup[-1]
'black'
>>> tup[-4]
'blue'
>>> tup[-6]
'red'
>>>
切片
注意:结果值不包含停止索引,如果 只有开始索引没有停止索引说明切片范围一直到最后
>>> tup1 = (10, 20, 30, 40, 50, 60, 70, 80, 90)
>>> tup1[2:7]
(30, 40, 50, 60, 70)
>>> tup1[2:] #没有停止索引,就一直到最后
(30, 40, 50, 60, 70, 80, 90)
>>> tup1[2:-1]
(30, 40, 50, 60, 70, 80)
>>>
3、修改元组
元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2
print (tup3)
输出
(12, 34.56, 'abc', 'xyz')
4、删除元组
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:
tup = ('Google', 'Runoob', 1997, 2000)
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)
以上实例元组被删除后,整个对象都没有了,自然会报找不到对象的错误,输出如下所示:
删除后的元组 tup :
Traceback (most recent call last):
File "TupTest.py", line 8, in <module>
print (tup)
NameError: name 'tup' is not defined
5、元组运算符
与字符串一样,元组之间可以使用 +、+=和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组。
- 计算元素个数
>>> len((1, 2, 3))
>>> 3
- 连接,c 就是一个新的元组,它包含了 a 和 b 中的所有元素。
>>> a = (1, 2, 3)
>>> b = (4, 5, 6)
>>> c = a+b
>>> c
>>> (1, 2, 3, 4, 5, 6)
- 连接,a 就变成了一个新的元组,它包含了 a 和 b 中的所有元素。
>>> a = (1, 2, 3)
>>> b = (4, 5, 6)
>>> a += b
>>> a
>>> (1, 2, 3, 4, 5, 6)
- 复制
>>> ('Hi!',) * 4
>>> ('Hi!', 'Hi!', 'Hi!', 'Hi!')
- 元素是否存在
>>> 3 in (1, 2, 3)
>>> True
- 迭代
for x in (1, 2, 3):
print (x, end=" ")
6、元组内置函数
Python元组包含了以下内置函数
- len(tuple):计算元组元素个数。
实例
>>> tuple1 = ('Google', 'Jd', 'Taobao')
>>> len(tuple1)
>>>3
- max(tuple):返回元组中元素最大值。
实例
>>> tuple2 = ('5', '4', '8')
>>> max(tuple2)
>>>'8'
- min(tuple):返回元组中元素最小值。
实例
>>> tuple2 = ('5', '4', '8')
>>> min(tuple2)
>>>'4'
- tuple(iterable):将可迭代系列转换为元组。
实例
>>> list1= ['Google', 'Taobao', 'Jd', 'Baidu']
>>> tuple1=tuple(list1)
>>> tuple1
>>> ('Google', 'Taobao', 'Jd', 'Baidu')
6、1 元组不可变
元组的不可变指的是元组所指向的内存中的内容不可变
>>> tuple2 = ('5', '4', '8')
>>> tuple[0] = '9' # 不支持修改元素
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'type' object does not support item assignment
>>> id(tuple2) # 查看内存地址
2431010567872
>>> tuple2 = (5,6,7)
>>> id(tuple2)
2431010676928 # 内存地址不一样了
>>>
7、元组的应用
7、1 打包和解包
当我们把多个用逗号分隔的值赋给一个变量时,多个值会打包成一个元组类型;当我们把一个元组赋值给多个变量时,元组会解包成多个值然后分别赋给对应的变量,如下面的代码所示。
>>> b = 2, 6, 9 #打包
>>> print(type(b))
<class 'tuple'>
>>> i, j, k = b #解包
>>> print(i, j, k)
2 6 9
>>>
在解包时,如果解包出来的元素个数和变量个数不对应,会引发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)
1 2 [3, 4, 5, 6, 7, 8, 9]
>>> a, b, c = [1, 10, 100]
>>> print(a, b, c)
1 10 100
>>> a, *b, c = 'hello'
>>> print(a, b, c)
h ['e', 'l', 'l'] o
>>> a, b, c = {'name': 'lucy', 'age': 16, 'weight': 86}
>>> print(a, b, c)
name age weight
>>>
有意思的是,如果 你对字典进行解包,仅仅是得到对应的键的值。
7、2 交换变量的值
在很多编程语言中,交换两个变量的值都需要借助一个中间变量才能做到,如果不用中间变量就需要使用比较晦涩的位运算来实现。在Python中,交换两个变量a和b的值只需要使用如下所示的代码。
a, b = b, a
如果要将三个变量a、b、c的值互换,即b赋给a,c赋给b,a赋给c,也可以如法炮制。
a, b, c = b, c, a
7、3 元组和列表的比较
这里还有一个非常值得探讨的问题,Python中已经有了列表类型,为什么还需要元组这样的类型呢?
- 元组是不可变类型,不可变类型更适合多线程环境,因为它降低了并发访问变量的同步化开销。
- 元组是不可变类型,通常不可变类型在创建时间和占用空间上面都优于对应的可变类型。我们可以使用sys模块的getsizeof函数来检查保存相同元素的元组和列表各自占用了多少内存空间。我们也可以使用timeit模块的timeit函数来看看创建保存相同元素的元组和列表各自花费的时间,代码如下所示。
import sys
import timeit
a = list(range(100000))
b = tuple(range(100000))
print(sys.getsizeof(a), sys.getsizeof(b)) # 900120 800056
print(timeit.timeit('[1, 2, 3, 4, 5, 6, 7, 8, 9]'))
print(timeit.timeit('(1, 2, 3, 4, 5, 6, 7, 8, 9)'))
元组和列表是可以相互转换的,list()、tuple()
# 将元组转换成列表
info = ('骆昊', 175, True, '四川成都')
print(list(info)) # ['骆昊', 175, True, '四川成都']
# 将列表转换成元组
fruits = ['apple', 'banana', 'orange']
print(tuple(fruits)) # ('apple', 'banana', 'orange')
列表和元组都是容器型的数据类型,即一个变量可以保存多个数据。列表是可变数据类型,元组是不可变数据类型,所以列表添加元素、删除元素、清空、排序等方法对于元组来说是不成立的。但是列表和元组都可以进行拼接、成员运算、索引和切片这些操作。