首页 > 编程语言 >Python常用数据结构之元组

Python常用数据结构之元组

时间:2023-04-20 14:06:26浏览次数:38  
标签:10 变量 Python 列表 print 100 数据结构 元组

前面的两节课,我们为大家讲解了 Python 中的列表,它是一种容器型的数据类型,通过列表类型的变量,我们可以保存多个数据并通过循环实现对数据的批量操作。当然,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)只是字符串和整数。我们可以通过下面的代码来加以验证。Python常用数据结构之元组

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 中,交换两个变量ab的值只需要使用如下所示的代码。

a, b = b, a

同理,如果要将三个变量abc的值互换,即b的值赋给ac的值赋给ba的值赋给c,也可以如法炮制。

a, b, c = b, c, a

需要说明的是,上面的操作并没有用到打包和解包语法,Python 的字节码指令中有ROT_TWOROT_THREE这样的指令可以直接实现这个操作,效率是非常高的。但是如果有多于三个变量的值要依次互换,这个时候是没有直接可用的字节码指令的,需要通过打包解包的方式来完成变量之间值的交换。

Python常用数据结构之元组

元组和列表的比较

这里还有一个非常值得探讨的问题,Python 中已经有了列表类型,为什么还需要元组这样的类型呢?这个问题对于初学者来说似乎有点困难,不过没有关系,我们先抛出观点,大家可以一边学习一边慢慢体会。

  1. 元组是不可变类型,不可变类型更适合多线程环境,因为它降低了并发访问变量的同步化开销。关于这一点,我们会在后面讲解并发编程的时候跟大家一起探讨。
  2. 元组是不可变类型,通常不可变类型在创建时间上优于对应的可变类型。我们可以使用timeit模块的timeit函数来看看创建保存相同元素的元组和列表各自花费的时间,timeit函数的number参数表示代码执行的次数。下面的代码中,我们分别创建了保存19的整数的列表和元组,每个操作执行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.633
0.078

说明:上面代码的执行结果因软硬件系统而异,在我目前使用的电脑上,执行10000000次创建列表的操作时间是0.633秒,而执行10000000次创建元组的操作时间是0.078秒,显然创建元组更快且二者时间上有数量级的差别。大家可以在自己的电脑上执行这段代码,把你的执行结果放到评论区,看看谁的电脑配置更厉害。

当然,Python 中的元组和列表类型是可以相互转换的,我们可以通过下面的代码来完成该操作。

infos = ('骆昊', 43, True, '四川成都')
# 将元组转换成列表
print(list(infos))  # ['骆昊', 43, True, '四川成都']

frts = ['apple', 'banana', 'orange']
# 将列表转换成元组
print(tuple(frts))  # ('apple', 'banana', 'orange')

总结

列表和元组都是容器型的数据类型,即一个变量可以保存多个数据,而且它们都是按一定顺序组织元素的有序容器。列表是可变数据类型元组是不可变数据类型,所以列表可以添加元素、删除元素、清空元素、排序反转,但这些操作对元组来说是不成立的。列表和元组都可以支持拼接运算成员运算索引运算切片运算等操作,后面我们要讲到的字符串类型也支持这些运算,因为字符串就是字符按一定顺序构成的序列,在这一点上三者并没有什么区别。我们推荐大家使用列表的生成式语法来创建列表,它不仅好用而且效率很高,是 Python 语言中非常有特色的语法。

标签:10,变量,Python,列表,print,100,数据结构,元组
From: https://blog.51cto.com/u_15739596/6209502

相关文章

  • python dataclasses定义默认值为可变类型(转)
    原文:https://zhuanlan.zhihu.com/p/59658886作者:没有50CM手臂网站:知乎 场景还原最近开发遇到一个问题是在python3.7的dataclass中不能使用可变的默认值,错误如下:@dataclassclassFoo:bar:list=[]#ValueError:mutabledefault<class'list'>forfieldaisn......
  • python a股量化解决方案
    baostockhttp://baostock.com/baostock/index.php/A股K线数据pytdxhttps://rainx.gitbooks.io/pytdx/content/pytdx_reader.html......
  • LeetCode Top100: 相交链表(Python)
    LeetCodeTop100:相交链表给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。图示两个链表在节点 c1 开始相交:题目数据 保证 整个链式结构中不存在环。注意,函数返回结果后,链表必须 保持其原......
  • 【备忘录设计模式详解】C/Java/JS/Go/Python/TS不同语言实现
    简介备忘录模式(MementoPattern)是一种结构型设计模式。这种模式就是在不破坏封装的条件下,将一个对象的状态捕捉(Capture)住,并放在外部存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用。备忘录模式的角色有三个......
  • LeetCode Top100: 环形链表(python)
     给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从0开始)。注意:pos 不作为参数进行传递 。仅仅是为......
  • Python 图像处理实用指南:11~12
    原文:Hands-OnImageProcessingwithPython协议:CCBY-NC-SA4.0译者:飞龙本文来自【ApacheCN计算机视觉译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。当别人说你没有底线的时候,你最好真的没有;当别人说你做过某些事的时候,你也最好真的做过。十一、深入学习图像处理——......
  • 理解 Python 的 Dataclasses第二篇(转)
    原文:https://zhuanlan.zhihu.com/p/59658598作者:没有50CM手臂网站:知乎这是Python最新的Dataclasses系列的第二部分内容。在第一部分里,我介绍了dataclasses的一般用法。这篇博客主要介绍另一个特征:dataclasses.field。我们已经知道Dataclasses会生成他们自身的__init__方法。......
  • 理解 Python 的 Dataclasses第一篇(转)
    原文:https://zhuanlan.zhihu.com/p/59657729作者:没有50CM手臂网站:知乎引言Dataclasses是一些适合于存储数据对象(dataobject)的Python类。你可能会问,什么是数据对象?下面是一个并不详尽的用于定义数据对象的特征列表:他们存储并表示特定的数据类型。例如:一个数字。对于那些熟悉......
  • python+playwright 学习-54 结合 gremlins.js 实现web 网页的mokey测试
    前言在Android应用测试里面有个mokey测试可以对app做稳定性的测试,在app里面随机乱点发送一些事件,看app会不会异常。这种做法,也称为Monkey测试或Fuzz测试,在移动应用程序开发中非常常见。Gremlins.js模拟随机用户操作:gremlins单击窗口中的任意位置,在表格中输入随机数......
  • PYTHON TXT 去空行
    withopen('file.txt','r')asf:lines=f.readlines()withopen('file.txt','w')asf:forlineinlines:ifline.strip():f.write(line)首先,我们使用`open()`函数打开文件,并使用`readlines()`方法读取文件中的所有......