Python3 元组tuple入门基础


Posted in Python onFebruary 09, 2020

Python 的元组与列表类似,不同之处在于元组的元素不能修改。

元组使用小括号,列表使用方括号。

元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。

实例(Python 3.0+)

>>>tup1 = ('Baidu', '3water', 1997, 2000)
>>> tup2 = (1, 2, 3, 4, 5 )
>>> tup3 = "a", "b", "c", "d" # 不需要括号也可以
>>> type(tup3)
<class 'tuple'>

创建空元组

tup1 = ()

元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运算符使用:

实例(Python 3.0+)

>>>tup1 = (50)
>>> type(tup1)  # 不加逗号,类型为整型
<class 'int'>
 
>>> tup1 = (50,)
>>> type(tup1)  # 加上逗号,类型为元组
<class 'tuple'>

元组与字符串类似,下标索引从0开始,可以进行截取,组合等。

访问元组

元组可以使用下标索引来访问元组中的值,如下实例:

实例(Python 3.0+)

#!/usr/bin/python3
 
tup1 = ('Baidu', '3water', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7 )
 
print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])

以上实例输出结果:

tup1[0]: Baidu
tup2[1:5]: (2, 3, 4, 5)

修改元组

元组中的元素值是不允许修改的,但我们可以对元组进行连接组合,如下实例:

实例(Python 3.0+)

#!/usr/bin/python3
 
tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')
 
# 以下修改元组元素操作是非法的。
# tup1[0] = 100
 
# 创建一个新的元组
tup3 = tup1 + tup2
print (tup3)

以上实例输出结果:

(12, 34.56, 'abc', 'xyz')

删除元组

元组中的元素值是不允许删除的,但我们可以使用del语句来删除整个元组,如下实例:

实例(Python 3.0+)

#!/usr/bin/python3
 
tup = ('Baidu', 'Jb51', 1997, 2000)
 
print (tup)
del tup
print ("删除后的元组 tup : ")
print (tup)

以上实例元组被删除后,输出变量会有异常信息,输出如下所示:

删除后的元组 tup :
Traceback (most recent call last):
File "test.py", line 8, 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 = ('Baidu', 'Taobao', '3water')

Python 表达式 结果 描述
L[2] '3water' 读取第三个元素
L[-2] 'Taobao' 反向读取,读取倒数第二个元素
L[1:] ('Taobao', '3water') 截取元素,从第二个开始后的所有元素。

运行实例如下:

>>> L = ('Baidu', 'Taobao', 'Jb51')
>>> L[2]
'Jb51'
>>> L[-2]
'Taobao'
>>> L[1:]
('Taobao', 'Jb51')

元组内置函数

Python元组包含了以下内置函数

序号 方法及描述 实例
1 len(tuple) 计算元组元素个数。 >>> tuple1 = ('Baidu', 'Jb51', 'Taobao') >>> len(tuple1) 3 >>>
2 max(tuple) 返回元组中元素最大值。 >>> tuple2 = ('5', '4', '8') >>> max(tuple2) '8' >>>
3 min(tuple) 返回元组中元素最小值。 >>> tuple2 = ('5', '4', '8') >>> min(tuple2) '4' >>>
4 tuple(iterable) 将可迭代系列转换为元组。 >>> list1= ['Baidu', 'Taobao', 'Jb51', 'Baidu'] >>> tuple1=tuple(list1) >>> tuple1 ('Baidu', 'Taobao', 'Jb51', 'Baidu')

关于元组是不可变的

所谓元组的不可变指的是元组所指向的内存中的内容不可变。

>>> tup = ('r', 'u', 'n', 'o', 'o', 'b')
>>> tup[0] = 'g'  # 不支持修改元素
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> id(tup)  # 查看内存地址
4440687904
>>> tup = (1,2,3)
>>> id(tup)
4441088800 # 内存地址不一样了

从以上实例可以看出,重新赋值的元组 tup,绑定到新的对象了,不是修改了原来的对象。

下面是其他网友的补充

tuple和list非常类似,但是tuple一旦初始化就不能修改,比如同样是列出同学的名字:

代码如下:

>>> classmates = ('Michael', 'Bob', 'Tracy')

现在,classmates这个tuple不能变了,它也没有append(),insert()这样的方法。其他获取元素的方法和list是一样的,你可以正常地使用classmates[0],classmates[-1],但不能赋值成另外的元素。不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。tuple的陷阱:当你定义一个tuple时,在定义的时候,tuple的元素就必须被确定下来,比如:

代码如下:

>>> t = (1, 2)
>>> t
(1, 2)

如果要定义一个空的tuple,可以写成():

代码如下:

>>> t = ()
>>> t
()

但是,要定义一个只有1个元素的tuple,如果你这么定义:

代码如下:

>>> t = (1)
>>> t
1

定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,因此,Python规定,这种情况下,按小括号进行计算,计算结果自然是1。

所以,只有1个元素的tuple定义时必须加一个逗号 ,来消除歧义:

代码如下:

>>> t = (1,)
>>> t
(1,)

Python在显示只有1个元素的tuple时,也会加一个逗号,,以免你误解成数学计算意义上的括号。

在来看一个"可变的"tuple:

代码如下:

>>> t = ('a', 'b', ['A', 'B'])
>>> t[2][0] = 'X'
>>> t[2][1] = 'Y'
>>> t
('a', 'b', ['X', 'Y'])

这个tuple定义的时候有3个元素,分别是'a','b'和一个list。不是说tuple一旦定义后就不可变了吗?怎么后来又变了?

别急,我们先看看定义的时候tuple包含的3个元素:当我们把list的元素'A'和'B'修改为'X'和'Y'后,tuple变为:表面上看,tuple的元素确实变了,但其实变的不是tuple的元素,而是list的元素。tuple一开始指向的list并没有改成别的list,所以,tuple所谓的"不变"是说,tuple的每个元素,指向永远不变。即指向'a',就不能改成指向'b',指向一个list,就不能改成指向其他对象,但指向的这个list本身是可变的!理解了"指向不变"后,要创建一个内容也不变的tuple怎么做?那就必须保证tuple的每一个元素本身也不能变。

tuple元素不可变有一种特殊情况,当元素是可变对象时。对象内部属性是可以修改的!tuple的不可变限制只是在一个纬度上:元素的类型。实现理解,tuple的元素所保存的内容(数值或内存地址)是不允许修改的,但地址映射的对象自身是可以修改的。

>>> a = (1,[3,2])
>>> a[1][0] = 1
>>> a
(1, [1, 2])
>>> a[1].append(3)
>>> a
(1, [1, 2, 3])
>>> del a[1][2]
>>> a
(1, [1, 2])
>>> del a[1]
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'tuple' object doesn't support item deletion
>>> del a[1][1]
>>> del a[1][0]
>>> a
(1, [])
>>>

字符串是一种特殊的tuple,支持部分tuple的运算符

>>> a = '12345'
>>> a[2]
'3'
>>> a[3:]
'45'
>>> type(a)
<class 'str'>
>>> a*2
'1234512345'
>>> 6 in a
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'in <string>' requires string as left operand, not int
>>> a
'12345'
>>> for x in a: print(x)
... 
1
2
3
4
5

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'])
User = collections.namedtuple('User', 'name age id')
user = User('tester', '22', '464643123')

print(user)

collections.namedtuple('User', 'name age id') 创建一个具名元组,需要两个参数,一个是类名,另一个是类的各个字段名。后者可以是有多个字符串组成的可迭代对象,或者是有空格分隔开的字段名组成的字符串(比如本示例)。具名元组可以通过字段名或者位置来获取一个字段的信息。

输出结果:

User(name='tester', age='22', id='464643123')

具名元组的特有属性:

类属性 _fields:包含这个类所有字段名的元组 类方法 _make(iterable):接受一个可迭代对象来生产这个类的实例 实例方法 _asdict():把具名元组以 collections.OrdereDict 的形式返回,可以利用它来把元组里的信息友好的展示出来

from collections import namedtuple

# 定义一个namedtuple类型User,并包含name,sex和age属性。
User = namedtuple('User', ['name', 'sex', 'age'])

# 创建一个User对象
user = User(name='Runoob', sex='male', age=12)

# 获取所有字段名
print( user._fields )

# 也可以通过一个list来创建一个User对象,这里注意需要使用"_make"方法
user = User._make(['Runoob', 'male', 12])

print( user )
# User(name='user1', sex='male', age=12)

# 获取用户的属性
print( user.name )
print( user.sex )
print( user.age )

# 修改对象属性,注意要使用"_replace"方法
user = user._replace(age=22)
print( user )
# User(name='user1', sex='male', age=21)

# 将User对象转换成字典,注意要使用"_asdict"
print( user._asdict() )
# OrderedDict([('name', 'Runoob'), ('sex', 'male'), ('age', 22)])

以上实例输出结果为:

('name', 'sex', 'age')
User(name='Runoob', sex='male', age=12)
Runoob
male
12
User(name='Runoob', sex='male', age=22)
OrderedDict([('name', 'Runoob'), ('sex', 'male'), ('age', 22)])

元组的一些特殊需求实现

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]
[9, 2, 3, 1, 2, 3, 4]
(9, 2, 3, 1, 2, 3, 4)

元组所指向的内存实际上保存的是元组内数据的内存地址集合(即 t[0], t[1]...t[n] 的内存地址),且元组一旦建立,这个集合就不能增加修改删除,一旦集合内的地址发生改变,必须重新分配元组空间保存新的地址集(元组类似 C 语言里的指针数组,只不过这个数组不能被修改)。

测试下面代码:

print("连接前:")
t1=(1,2,"3")
t2=("4",5,["d1","d2"])
print("t1=",t1)
print("t2=",t2)
print("t1:",id(t1))
print("t2:",id(t2))
print("t1[0]:",id(t1[0]))
print("t1[1]:",id(t1[1]))
print("t1[2]:",id(t1[2]))
print("t2[0]:",id(t2[0]))
print("t2[1]:",id(t2[1]))
print("t2[2]:",id(t2[2]))
print("连接后:")
t1= t1+t2
print("t1(t1+t2):",id(t1))
print("t1[0]:",id(t1[0]))
print("t1[1]:",id(t1[1]))
print("t1[2]:",id(t1[2]))
print("t1[3]:",id(t1[3]))
print("t1[4]:",id(t1[4]))
print("t1[5]:",id(t1[5]))
t1[5].append("d3")
print("t1[5]增加d3:")
print("t1[5]=",t1[5])
print("t1[5]:",id(t1[5]))
print("t2=",t2)

输出:

连接前:
t1= (1, 2, '3')
t2= ('4', 5, ['d1', 'd2'])
t1: 1719219799168
t2: 1719219799528
t1[0]: 1378249760
t1[1]: 1378249792
t1[2]: 1719200188208
t2[0]: 1719199042336
t2[1]: 1378249888
t2[2]: 1719219441608
连接后:
t1(t1+t2): 1719222365256
t1[0]: 1378249760
t1[1]: 1378249792
t1[2]: 1719200188208
t1[3]: 1719199042336
t1[4]: 1378249888
t1[5]: 1719219441608
t1[5]增加d3:
t1[5]= ['d1', 'd2', 'd3']
t1[5]: 1719219441608
t2= ('4', 5, ['d1', 'd2', 'd3'])

测试结论:元组 t1 跟 t2 连接并赋值 t1 后,t1 地址发生变化(因地址集合变化),t1[0], t1[1], t1[2], t2[0], t2[1], t2[2] 地址不变且保存在连接后的 t1,元组内数据根据自身类型确定是否可修改值(t1[0]..t1[4] 分别为不可修改的数据类型,t1[5] 为可修改的列表),连接后 t1[5] 跟 t2[2] 地址一样,t1[5] 变化将会导致 t2[2] 变化。

通过间接方法修改元组:

tuple1 = (1,2,4,5)
tuple2 = tuple1[:2] + (3,) + tuple1[2:]
print(tuple2)

输出结果为:

(1, 2, 3, 4, 5)

关于如何修改元组的几个脱裤子放屁的方法:

# 方法一,赋值修改法
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)
#输出: ['谁', '说', '元', '组', '不', '能', '改']

这篇文章就介绍到这了,希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用zip合并相邻列表项的方法示例
Mar 17 Python
python 读取txt中每行数据,并且保存到excel中的实例
Apr 29 Python
Python3.7实现中控考勤机自动连接
Aug 28 Python
Python运维自动化之nginx配置文件对比操作示例
Aug 29 Python
Python函数any()和all()的用法及区别介绍
Sep 14 Python
Python利用递归实现文件的复制方法
Oct 27 Python
python url 参数修改方法
Dec 26 Python
利用python实现短信和电话提醒功能的例子
Aug 08 Python
python开根号实例讲解
Aug 30 Python
python 如何引入协程和原理分析
Nov 30 Python
python中的对数log函数表示及用法
Dec 09 Python
pytorch中的torch.nn.Conv2d()函数图文详解
Feb 28 Python
Python3列表List入门知识附实例
Feb 09 #Python
Python 动态变量名定义与调用方法
Feb 09 #Python
python函数定义和调用过程详解
Feb 09 #Python
详解python 破解网站反爬虫的两种简单方法
Feb 09 #Python
Python字典深浅拷贝与循环方式方法详解
Feb 09 #Python
Python文件操作方法详解
Feb 09 #Python
Python列表操作方法详解
Feb 09 #Python
You might like
codeigniter中测试通过的分页类示例
2014/04/17 PHP
PHP实现的多彩标签效果代码分享
2014/08/21 PHP
PHP也能干大事之PHP中的编码解码详解
2015/04/20 PHP
php中使用array_filter()函数过滤数组实例讲解
2021/03/03 PHP
麦鸡的TAB切换功能结合了javascript和css
2007/12/17 Javascript
用jquery设置按钮的disabled属性的实现代码
2010/11/28 Javascript
ASP.NET jQuery 实例5 (显示CheckBoxList成员选中的内容)
2012/01/13 Javascript
JS如何判断移动端访问设备并解析对应CSS
2013/11/27 Javascript
Bootstrap每天必学之导航组件
2016/04/25 Javascript
JS iFrame加载慢怎么解决
2016/05/13 Javascript
微信js-sdk界面操作接口用法示例
2016/10/12 Javascript
深入理解jQuery.data() 的实现方式
2016/11/30 Javascript
vue按需加载组件webpack require.ensure的方法
2017/12/13 Javascript
JavaScript门道之标准库
2018/05/26 Javascript
jquery ui 实现 tab标签功能示例【测试可用】
2019/07/25 jQuery
JavaScript实现HSL拾色器
2020/05/21 Javascript
python中argparse模块用法实例详解
2015/06/03 Python
matplotlib绘制动画代码示例
2018/01/02 Python
python如何通过twisted实现数据库异步插入
2018/03/20 Python
python实现QQ邮箱/163邮箱的邮件发送
2019/01/22 Python
python3爬虫学习之数据存储txt的案例详解
2019/04/24 Python
如何用Anaconda搭建虚拟环境并创建Django项目
2020/08/02 Python
Python开发.exe小工具的详细步骤
2021/01/27 Python
详解HTML5常用的语义化标签
2019/09/27 HTML / CSS
世界上最好的儿童品牌:AlexandAlexa
2018/01/27 全球购物
如果让你测试一台高速激光打印机,你都会进行哪些测试
2012/12/04 面试题
卫校护理专业毕业生求职信
2013/11/26 职场文书
园林设计专业毕业生求职信
2014/03/23 职场文书
销售2014年度工作总结
2014/12/08 职场文书
2014年干部培训工作总结
2014/12/17 职场文书
共青团员自我评价
2015/03/10 职场文书
大学生实习推荐信
2015/03/27 职场文书
会议主持词结束语
2015/07/03 职场文书
演讲稿之我的初心我的成长
2019/08/12 职场文书
Nginx+Tomcat负载均衡集群的实现示例
2021/10/24 Servers
Vue router配置与使用分析讲解
2022/12/24 Vue.js