Python 的元组与列表类似,不同之处在于元组的元素不能修改
元组使用小括号,列表使用方括号
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可
tup1 = ('Google', 'runO', 1997, 2007)
tup = "a", "b", "c", "d" # 不需要括号也可以
print(type(tup))
创建空元组
tup1 = ()
元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用
tup1 = (50) # 不加逗号,类型为整型元组与字符串类似,下标索引从0开始,可以进行截取,组合等
print(type(tup1))
tup1 = (50,) # 加上逗号,类型为元组
print(type(tup1))
访问元组
元组可以使用下标索引来访问元组中的值
tup1 = ('Google', 'Run', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7)
print('tup1[0]:', tup1[0])
print('tup2[1:5]:', tup2[1:5])
修改元组
元组中的元素值是不允许修改的,但可以对元组进行连接组合
tup1 = (12, 34.56)输出
tup2 = ('abc', 'xyz')
# 以下修改元组元素操作是非法的
# tup1[0] = 100
# 创建一个新的元组
tup3 = tup1 + tup2
print(tup3)
(12, 34.56, 'abc', 'xyz')
删除元组
元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组
tup = ('Google', 'Run', 1997, 2000)输出
print(tup)
print('删除后的元组 tup:')
del tup
print(tup)
Traceback (most recent call last):
File "F:/bo/SoftwarePractice/Python/Demo/demo.py", line 42, in <module>
print(tup)
NameError: name 'tup' is not defined
元组运算符
与字符串一样,元组之间可以使用 + 号和 * 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组
Python 表达式 | 结果 | 描述 |
---|---|---|
len((1, 2, 3)) | 3 | 计算元素个数 |
(1, 2, 3) + (4, 5, 6) | (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,) | 1 2 3 | 迭代 |
元组索引,截取
因为元组也是一个序列,所以可以访问元组中的指定位置的元素,也可以截取索引中的一段元素
L = ('Google', 'Taobao', 'Runoob')
Python 表达式 | 结果 | 描述 |
---|---|---|
L[2] | 'Runoob' | 读取第三个元素 |
L[-2] | 'Taobao' | 反向读取;读取倒数第二个元素 |
L[1:] | ('Taobao', 'Runoob') | 截取元素,从第二个开始后的所有元素。 |
元组内置函数
Python元组包含了以下内置函数
小结:
tuple和list非常类似,但是tuple一旦初始化就不能修改
因为tuple不可变,所以代码更安全
如果可能,能用tuple代替list就尽量用tuple。tuple的陷阱:当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来
tuple所谓的"不变"是说,tuple的每个元素,指向永远不变
即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的
理解了"指向不变"后,要创建一个内容也不变的tuple怎么做?那就必须保证tuple的每一个元素本身也不能变
也就是
tuple元素不可变有一种特殊情况,当元素是可变对象时。对象内部属性是可以修改的
tuple的不可变限制只是在一个纬度上:元素的类型。实现理解,tuple的元素所保存的内容(数值或内存地址)是不允许修改的,但地址映射的对象自身是可以修改的
字符串是一种特殊的tuple,支持部分tuple的运算符
Python元组的升级版本 -- namedtuple(具名元组)
因为元组的局限性:不能为元组内部的数据进行命名,所以往往我们并不知道一个元组所要表达的意义,所以在这里引入了 collections.namedtuple 这个工厂函数,来构造一个带字段名的元组。具名元组的实例和普通元组消耗的内存一样多,因为字段名都被存在对应的类里面。这个类跟普通的对象实例比起来也要小一些,因为 Python 不会用 __dict__ 来存放这些实例的属性
namedtuple 对象的定义如以下格式:
collections.namedtuple(typename, field_names, verbose=False, rename=False)
返回一个具名元组子类 typename,其中参数的意义如下:
- typename:元组名称
- field_names: 元组中元素的名称
- rename: 如果元素名称中含有 python 的关键字,则必须设置为 rename=True
- verbose: 默认就好
输出import collections
# 两种方法来给 namedtuple 定义方法名
#User = collections.namedtuple('User', ['name', 'age', 'id'])
# 定义一个namedtuple类型User,并包含name,age和id属性
User = collections.namedtuple('User', ['name', 'age', 'id'])
# 创建一个User对象
user = User('tester', '22', '464643123')
print(user)
# 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
user = User._make(['Runoob', 'male', 12])
User(name='tester', age='22', id='464643123')
具名元组的特有属性:
类属性 _fields:包含这个类所有字段名的元组 类方法 _make(iterable):接受一个可迭代对象来生产这个类的实例 实例方法 _asdict():把具名元组以 collections.OrdereDict 的形式返回,可以利用它来把元组里的信息友好的展示出来
元组的一些特殊需求实现
1、定义元组后,根据不同的情形增加新的元组内容
t1 = (1, 2, 3)输出
for i in range(1,5):
t2 = (i,)
t1 = t1+t2
print(t1)
(1, 2, 3, 1, 2, 3, 4)
2、修改元组内的特定位置的值
t1 = (1, 2, 3)输出
for i in range(1, 5):
t2 = (i,)
t1 = t1 + t2
print(t1)
l1 = list(t1)
print(l1)
l1[0] = 9
print(l1)
t1 = tuple(l1)
print(t1)
(1, 2, 3, 1, 2, 3, 4)
(1, 2, 3, 1, 2, 3, 4)
[1, 2, 3, 1, 2, 3, 4]
[9, 2, 3, 1, 2, 3, 4]
(9, 2, 3, 1, 2, 3, 4)
元组所指向的内存实际上保存的是元组内数据的内存地址集合(即 t[0], t[1]...t[n] 的内存地址),且元组一旦建立,这个集合就不能增加修改删除,一旦集合内的地址发生改变,必须重新分配元组空间保存新的地址集(元组类似 C 语言里的指针数组,只不过这个数组不能被修改)
通过间接方法修改元组
tuple1 = (1, 2, 4, 5)
tuple2 = tuple1[:2] + (3,) + tuple1[2:]
print(tuple2)
# 方法一,赋值修改法
tup = (4,5,6,7,8)
tup = ('谁', '说', '元', '组', '不', '能', '改')
print(tup)
#输出: ('谁', '说', '元', '组', '不', '能', '改')
#方法二、中间变量法
tup = (4, 6, 7,8, 9, 10 ,0)
tup = list(tup)
list2 = ['谁', '说', '元', '组', '不', '能', '改']
for i in range(7):
tup[i] = list2[i]
print(tup)
#输出: ['谁', '说', '元', '组', '不', '能', '改']