当前位置: 首页 > news >正文

元组啊,不就是不可变的列表吗?

在这里插入图片描述
B站|公众号:啥都会一点的研究生

相关阅读

整理了几个100%会踩的Python细节坑,提前防止脑血栓
整理了十个100%提高效率的Python编程技巧,更上一层楼
Python-列表,从基础到进阶用法大总结,进来查漏补缺
Python-元组,从基础到进阶用法大总结及与列表核心区别,进来查漏补缺
Python-字典,从基础到进阶用法大总结,进来查漏补缺
Python-集合,从基础到进阶大总结,进来查漏补缺
这些包括我在内都有的Python编程陋习,趁早改掉
订阅专栏 ===> Python

问:元组是什么

答:呃,呃,内个,嗷,不就是“不可变的列表”嘛。

这个概括对吗?不能说对错,只能说概括不完全,元组除开用作不可变的列表,另一个常被忽略但极其实用的作用是,用于没有字段名的记录,本期我试图和大家一起学习归纳元组的常用方法,争取更上一层楼

首先来看看大家熟知的用法,用作不可变的列表,一句话概括就是,除了跟增删元素相关的方法外,元组支持列表的其他所有方法,为了方便说明,使用dir()分别查看列表与元组的内置方法与属性

dir(list)
# ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__delitem__', 
'__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', 
'__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', 
'__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
 '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__',
  '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 
  'remove', 'reverse', 'sort']

dir(tuple)
# ['__add__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', 
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', 
'__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__',
 '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', 
 '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']

使用help()则可以查看内置方法与属性的说明,知道大家十有八九不会再逐个help查看,行吧,我来吧,带大家一一查看对比列表与元组中除开object类支持的方法外的其他方法和属性,以列表为参考进行比照

首先看属性,列表与元组都支持的有这些

s.__add__(s2)     # 拼接,s + s2,不改变s
s.__contains__(e) # s是否包含e,e in s
s.__getitem__(p)  # 获取s中位置p的元素,s[p]
s.__iter__()      # 获取s的迭代器
s.__len__()       # 获取元素数量,len(s)
s.__mul__(n)      # n个s的重复拼接,s * n,不改变s
s.__rmul__(n)     # 反向拼接,n * s

然后就是列表支持但元组不支持的

s.__iadd__(s2)      # 拼接, s += s2,改变s
s.__delitem__(p)    # 删除s中位于p的元素 del s[p]
s.__imul__(n)       # n个s的重复拼接,s *= n,改变s
s.__reversed__()    # 返回 s 的倒序迭代器
s.__setitem__(p, e) # 将s中位置p的元素替换为e,s[p] = e

接着,我们再一起来看看列表与元组都支持的方法

s.count(e) # e在s中的个数
s.index(e) # e在s中第一次出现的位置索引

是的,没了,紧接着看看列表支持但元组不支持的方法

s.append(e)              # 在s尾部新增元素
s.clear()                # 清空s所有元素,保留s对象
s.copy()                 # 浅拷贝s
s.extend(it)             # 将可迭代对象it追加给s
s.insert(p, e)           # 在s的p位置之前插入元素e
s.pop([p])               # 删除s中最后或(可选的)位于p的元素,并返回它的值
s.remove(e)              # 删除 s 中的第一次出现的e值
s.reverse()              # 把 s 的元素倒序排列,改变s
s.sort([key], [reverse]) # 对s中的元素进行排序,可选的参数有键(key)和是否倒序(reverse),改变s

OK,归纳完毕,想必大家对元组充当不可变列表,哪些可用,哪些不可用有了进一步了解,我是不会主动问大家要三连的

接下来继续看看另一个用途,数据记录,如果仅把元组理解为不可变的列表,那所含元素的总数和对应位置似乎就变得可有可无,但若当成字段集合,那么这些信息就变得很重要了,举些例子来说明

比如,在元组中存放直线的斜率与截距

line_k_b = (1.0322, -10.6667) # k, b

元组同样支持存放不同类型的数据

name, age, height, weight = ('CaiXukong', 30, 142.01, 180.02)

当数据增多时,通常还会以元组列表的形式存放并且搭配循环遍历,使用%格式运算符可以匹配元组中对应元素

user_infos = [('ZS', '001'), ('LS', '002'), ('WW', '003')]

for user_info in user_infos:
    print('%s/%s' % user_info)
    
"""
ZS/001
LS/002
WW/003
"""

此外,还可以使用拆包提取元素

user_infos = [('ZS', '001'), ('LS', '002'), ('WW', '003')]

for name, uid in user_infos:
    print(name)
    
"""
ZS
LS
WW
"""

关于拆包,最常见的就是平行赋值,比如之前的例子,把一个可迭代对象中的元素赋值到对应变量组成的元组中,对应变量组成的元组也就是说其实name, age, height, weight也为元组

name, age, height, weight = ('CaiXukong', 30, 142.01, 180.02)

说到这里当然得提一下利用这个特性快速进行值交换的例子,我们可以使用如下方法交换两个变量的值

b, a = a, b

然后通常搭配*运算符把一个可迭代对象拆开作为函数的参数,比如使用divmod得到10除以8的商和余数,提一嘴,其实函数返回值也是元组类型

divmod(10, 8) # 1, 2

type(divmod(10, 8)) # <class 'tuple'>

将10和8存入元组中并结合*运算符喂给函数同样达到目的

data = (10, 8)
quotient, remainder = divmod(*data)

# quotient : 1
# remainder : 2

但有时候不是对所有数据感兴趣,比如只会用到余数,那么则可以使用_占位符处理这种情况

data = (10, 8)
_, remainder = divmod(*data)

# remainder : 2

讲到这个,那如果我不感兴趣的数据很多怎么办,诶没关系,*运算符可以助你宠幸关心的数据,我们知道在Python中经常使用*args来获取不确定的参数,这个用法也被扩展到了平行赋值中,一起来看看这个例子

a, b, *rest = range(10)
# 0 1 [2, 3, 4, 5, 6, 7, 8, 9]

a, b, *rest = range(3)
# 0 1 [2]

a, b, *rest = range(2)
# 0 1 []

虽然这个运算符只能出现在一个变量名之前,但是这个变量可以在赋值表达式的任意位置出现,不止尾部,比如中间和头部

a, *middle, b = range(10)
# 0 [1, 2, 3, 4, 5, 6, 7, 8] 9

*head, b, c = range(10)
# [0, 1, 2, 3, 4, 5, 6, 7] 8 9

元组的拆包同样也可以用于嵌套结构,比如这个例子

*head, (b, c) = (1, 2, (3, 4)) 
# [1, 2] 3 4

注意了如果bc不加括号,则得到的结果完全就不同了

*head, b, c = (1, 2, (3, 4)) 
# [1] 2 (3, 4)

讲完了拆包,下一个要讲的则是具名元组namedtuple,它继承了普通元组的属性,那是干嘛的呢,元组如果作为记录来用,缺少给记录的字段命名的功能。而namedtuple常用来构建一个带字段名的元组和一个有名字的类,怎么用呢,来看看这个例子

先看第二行,创建一个具名元组需要两个参数,一个类名,一个该类各字段的名字,后者可以是由若干字符串组成的可迭代对象,或由空格分开的字段名组成的单字符串

下一行,存放在对应字段里的数据要以一串参数的形式传入,然后便可以通过字段名或者位置来获取一个字段的信息

from collections import namedtuple
User = namedtuple('User', ['name', 'age', 'height', 'weight'])
# User = namedtuple('User', 'name age height weight')
CaiXukang = User('CaiXukang', 30, 142.01, 180.02)

print(CaiXukang.weight) # 180.02

ok,以上呢就是本期的全部内容,整理不易,有任何错误与补充欢迎在评论区指出,我是啥都生,我们下期再见。

相关文章:

  • Java练习题
  • 蓝桥杯跑步锻炼.c语言
  • java计算机毕业设计妇女健康保健系统源码+mysql数据库+系统+lw文档+部署
  • 第十四届蓝桥杯(web应用开发) 模拟赛2期 -大学组
  • 用Python代码画世界杯吉祥物拉伊卜(附代码)
  • 大规模异构图召回在美团到店推荐广告的应用
  • 在大厂工作是这样的
  • [附源码]SSM计算机毕业设计民宿客栈管理系统JAVA
  • FPGA片内RAM读写测试实验+逻辑分析仪ila
  • 【数据结构】七种排序方法,一篇文章掌握
  • 【web前端开发】HTML知识点超详细总结
  • C++ 语言学习 day11 复习(3)
  • 网络编程基础知识
  • 【用户画像】应用场景
  • 表白墙(前端+后端+数据库)
  • 2017届校招提前批面试回顾
  • Druid 在有赞的实践
  • Java-详解HashMap
  • java中具有继承关系的类及其对象初始化顺序
  • k8s如何管理Pod
  • k个最大的数及变种小结
  • Linux CTF 逆向入门
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Python学习之路16-使用API
  • SQLServer之索引简介
  • underscore源码剖析之整体架构
  • 初识MongoDB分片
  • 理清楚Vue的结构
  • 前端自动化解决方案
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 深入浅出webpack学习(1)--核心概念
  • 新手搭建网站的主要流程
  • 一个6年java程序员的工作感悟,写给还在迷茫的你
  • 原生 js 实现移动端 Touch 滑动反弹
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​力扣解法汇总946-验证栈序列
  • # Java NIO(一)FileChannel
  • #laravel 通过手动安装依赖PHPExcel#
  • #Z2294. 打印树的直径
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (13):Silverlight 2 数据与通信之WebRequest
  • (2)(2.4) TerraRanger Tower/Tower EVO(360度)
  • (JSP)EL——优化登录界面,获取对象,获取数据
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (算法设计与分析)第一章算法概述-习题
  • (推荐)叮当——中文语音对话机器人
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)重识new
  • *p++,*(p++),*++p,(*p)++区别?
  • .NET Core中的去虚
  • .NET8.0 AOT 经验分享 FreeSql/FreeRedis/FreeScheduler 均已通过测试
  • .NET单元测试
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)