Python技法1:变长和定长序列拆分
Python中的任何序列(可迭代的对象)都可以通过赋值操作进行拆分,包括但不限于元组、列表、字符串、文件、迭代器、生成器等。
元组拆分
元组拆分是最为常见的一种拆分,示例如下:
p = (4, 5)
x, y = p
print(x, y) # 4 5
如果写成
x, y, z = p
那么就会抛出ValueError异常:“not enough values to unpack (expected 3, got 2)”
如果写成
p = (4, 5, 6)
x, y = p
那么就会抛出ValueError异常:“too many values to unpack (expected 2)”
字符串拆分
字符串的拆分示意如下:
s = 'Hello'
a, b, c, d, e = s
print(a) # H
拆分时丢弃值
如果在拆分时想丢弃某些特定的值,可以用一个用不到的变量名来作为丢弃值的名称(常选'_'做为变量名),如下所示:
s = 'Hello'
a, b, _, d, _ = s
print(a) # H
嵌套序列拆分
Python也提供简洁的对嵌套序列进行拆分的语法。如下所示我们对一个比较复杂的异质列表进行拆分:
data = ['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, (year, month, day) = data
print(year) # 2000
如果你想完整地得到(2000, 12, 21)这个表示时间戳的元组,那么你就得这样写:
data = ['zhy', 50, 123.0, (2000, 12, 21)]
name, shares, price, date = data
print(date) # (2000, 12, 21)
从任意长度的可迭代对象中拆分
之前我们说过,如果我们想从可迭代对象中分解出\(N\)个元素,但如果这个可迭代对象长度超过\(N\),则会抛出异常"too many values to unpack"。针对这个问题的解决方案是采用"*"表达式。
比如我们给定学生的分数,想去掉一个最高分和一个最低分,然后对剩下的学生求平均分,我们可以这样写:
def avg(data: list):
return sum(data)/len(data)
# 去掉最高分,最低分然后做均分统计
def drop_first_last(grades):
first, *middle, last = grades
return avg(middle)
print(drop_first_last([1,2,3,4])) # 2.5
还有一种情况是有一些用户记录,记录由姓名+电子邮件+任意数量的电话号码组成,则我们可以这样分解用户记录:
record = ['zhy', 'zhy1056692290@qq.com', '773-556234', '774-223333']
name, email, *phone_numbers = record
print(phone_numbers) # ['773-556234', '774-223333']
事实上,如果电话号码为空也是合法的,此时phone_numbers为空列表。
record = ['zhy', 'zhy1056692290@qq.com']
name, email, *phone_numbers = record
print(phone_numbers) # []
还有一种使用情况则更为巧妙。如果我们需要遍历变长元组组成的列表,这些元组长度不一。那么此时*表达式可大大简化我们的代码。
records = [('foo', 1, 2), ('bar', 'hello'), ('foo', 3, 4)]
for tag, *args in records:
if tag == 'bar':
print(args)
# ['hello']
在对一些复杂的字符串进行拆分时,*表达式也显得特别有用。
line = "nobody:*:-2:-2:-2:Unprivileged User:/var/empty:/usr/bin/false"
uname, *fields, home_dir, sh = line.split(':')
print(home_dir) # /var/empty
*表达式也可以和我们前面说的嵌套拆分和变量丢弃一起结合使用。
record = ['ACME', 50, 123.45, (128, 18, 2012)]
name, *_, (*_, year) = record
print(year) # 2012
最后再介绍*表达式用于递归函数的一种黑魔法,比如与递归求和结合可以这样写:
items = [1, 10, 7, 4, 5, 9]
def sum(items):
head, *tail = items
return head + sum(tail) if tail else head
print(sum(items)) # 36
不过,Python由于自身递归栈的限制,并不擅长递归。我们最后一个递归的例子可以做为一种学术上的尝试,但不建议在实践中使用它。
参考文献
- [1] Martelli A, Ravenscroft A, Ascher D. Python cookbook[M]. " O'Reilly Media, Inc.", 2005.
Python技法1:变长和定长序列拆分的更多相关文章
- loadrunner socket协议问题归纳(4)---buffer接收变长和定长的数据
测试场景:聊天系统 用户登录后,要先向服务器发送用户名,然后可以发送聊天信息,同时也可以接受聊天信息. 如果接受的字符为定长时,可以设定接受长度.recv buf2 66 #include " ...
- 报文格式:xml 、定长报文、变长报文
目前接触到的报文格式有三种:xml .定长报文.变长报文 . 此处只做简单介绍,日后应该会深入学习到三者之间如何解析,再继续更新.——2016.9.23 XML XML 被设计用来传输和存储数据. H ...
- 快学Scala 第三课 (定长数组,变长数组, 数组循环, 数组转换, 数组常用操作)
定长数组定义: val ar = new Array[Int](10) val arr = Array("aa", "bb") 定长数组赋值: arr(0) = ...
- Python 数据处理----对定长数据的处理
场景: 有时候我们对大量数据进行处理,对性能要求很高,而且数据都是定长的,比如对移动信息登记表进行处理:名字 身份证信息 手机号码 这些都是定长的,今天小花来教大家如何对此类数据进行处理. 步骤一: ...
- 定长内存池之BOOST::pool
内存池可有效降低动态申请内存的次数,减少与内核态的交互,提升系统性能,减少内存碎片,增加内存空间使用率,避免内存泄漏的可能性,这么多的优点,没有理由不在系统中使用该技术. 内存池分类: 1. ...
- django使用pyecharts(6)----django加入echarts_增量更新_定长_坐标轴定长
六.Django 前后端分离_定时增量更新图表(坐标轴定长) 1.安装 djangorestframework linux pip3 install djangorestframework windo ...
- django使用pyecharts(5)----django加入echarts_增量更新_定长
五.Django 前后端分离_定时增量更新图表定长数据 1.安装 djangorestframework linux pip3 install djangorestframework windows ...
- Netty(四)分隔符与定长解码器的使用
TCP以流的形式进行数据传输,上层的应用协议为了对消息进行划分,往往采用如下的4种方式. (1)消息长度固定,累计读到长度总和为定长len的报文后,就认为读取到了一个完整的消息:然后重新开始读取下一个 ...
- javascript实现数据结构:串--定长顺序存储表示以及kmp算法实现
串(string)(或字符串)是由零个或多个字符组成的有限序列.串中字符的数目称为串的长度.零个字符的串称为空串(null string),它的长度为零. 串中任意个连续的字符组成的子序列称为该串的子 ...
随机推荐
- 宙斯盾 DDoS 防护系统“降本增效”的云原生实践
作者 tomdu,腾讯云高级工程师,主要负责宙斯盾安全防护系统管控中心架构设计和后台开发工作. 导语 宙斯盾 DDoS 防护系统作为公司级网络安全产品,为各类业务提供专业可靠的 DDoS/CC 攻击防 ...
- 2.2 DDD Layers & Clean Architecture DDD分层和简洁架构
DDD Layers & Clean Architecture DDD分层和简洁架构 There are four fundamental layers of a Domain Driven ...
- [技术博客] 敏捷软工——JavaScript踩坑记
[技术博客] 敏捷软工--JavaScript踩坑记 一.一个令人影响深刻的坑 1.脚本语言的面向对象 面向对象特性是现代编程语言的基本特性,JavaScript中当然集成了面向对象特性.但是Java ...
- 基于jpa的specification实现动态查询
spring data jpa为我们实现简单的crud操作提供了极大的方便.但大部分情况下,系统中都存在大量的动态查询操作,这个时候就可以借助spring data jpa的 Specificatio ...
- 关于下载pyton第三方库的细节
1.下载Python第三方库有时候国外的网站网速很不好,需要选择国内的镜像网站去下载 阿里云 http://mirrors.aliyun.com/pypi/simple 中国科技大学 https: ...
- matlab添加永久路径
addpath('D:\MATLAB6p5\toolbox\svm'); 临时添加路径,不能添加子目录 addpath(genpath('D:\MATLAB6p5\toolbox\svm'));临时添 ...
- buff/cache 占用过高解决方法
cache 读磁盘时,数据从磁盘读出后,暂留在缓冲区(cache),为后续程序的使用做准备 buffer 写磁盘时,先保存到磁盘缓冲区(buffer),然后再写入到磁盘 三条命令: #echo 1 & ...
- Centos 7 成功安装 dosbox 解决 "error: expected primary-expression before ‘,’ token" 错误
dosbox-0.74 bug 修复版下载: http://download.csdn.net/detail/yangbodong22011/9663271 注意:这篇博客解决了下面这个问题,如果你也 ...
- k8s入坑之路(13)服务迁移(定时任务 微服务 传统服务)
定时任务迁移kubernetes 服务迁移步骤 1.安装好java 2.安装好maven 项目打包 mvn package 测试传参运行 java -cp cronjob-demo-1.0-SNAPS ...
- 集合概述&集合之List接口
集合与数组存储概述 集合.数组都是对多个数据进行存储操作的结构,简称Java容器.此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库中) 数组存储的特点: ...