10、Python之写出更加Pythonic的代码:unpacking拆包机制

news2024/11/15 12:37:10

引言

有些小伙伴有其他编程语言的学习、使用的经验,然后迁移到Python。一般会比完全的新手小白,更快速地把Python用起来。这是他们的优势,但也是他们的劣势。
之所以这么说,是因为从其他编程语言带过来的,除了相通的编程思维、框架性的东西,还有编程语言的使用习惯。
而这些其他编程语言中的使用习惯,就会导致他们写出来的Python代码不是那么的Pythonic,当然,这是一种感觉。
虽说我们首要追求的是能用、够用。但是,偶尔也要稍微留意一下。就好像学习英语一样,虽然不追求能操着一口正宗的英伦腔,但也不应该对自己的chinglish迷之自信。
此外,故步自封于其他编程语言中的编程习惯,也可能限制我们更加灵活、便捷地发挥Python中的强大特性。

变量值交换

其他语言中,如果需要交换两个变量,通常需要引入一个中间变量,比如:

a = 5
b = 10
c = b
b = a
a = c

在Python中还这样写,就显得有些冗余、不够地道了。
其实,在Python中有一种更加简便的写法:

x = 5
y = 10
x, y = y, x

不需要引入中间变量,直接完成变量值的交换。我看有些地方把Python中的这种变量值交换,称之为unpacking机制。所以,我在今天的这篇讲解unpacking机制的文章中提到了这一点。

但是,也许是Python不同版本、Python解释器实现的差异,在我的Python3.11、CPython解释器的环境下,查看对应的字节码,发现并没有用到unpacking机制,而是Python中提供了一个用于进行栈顶两个值交换的swap指令。对应的字节码指令及解释,如下图所示:感兴趣的可以自行查看自己环境中变量值交换的实现。

基础unpacking机制

接下来,说回今天的主题,unpacking机制。
既然是unpacking,有些地方翻译为拆包,自然首先要有包可拆。这里所谓的拆包,其实是针对容器/集合类型的数据结构来说的。

通常情况下,我们把一个列表、元组或者是字典中的元素取出来,可以使用下标索引的方式。
比如,有如下场景:
我们有一些人员信息存放在一个列表中,每个列表元素是一个元组,元组中的元素,分别是姓名、年龄、性别。
现在,我们需要遍历人员信息的这个列表,然后将人员信息进行格式化打印输出。
使用下标索引的方式,可以这样实现:

persons = [('张三', 18, '女'), ('小红', 23, '男')]
for p in persons:
    name = p[0]
    age = p[1]
    gender = p[2]
    print(f"姓名: {name}, 年龄: {age}, 性别: {gender}")

但是,这样的写法,不够地道,没有使用Python给我们提供的更加好用的写法。
接下来,我们用unpacking的方式重新写一下:

# unpacking
persons = [('张三', 18, '女'), ('小红', 23, '男')]
for p in persons:
    name, age, gender = p
    print(f"姓名: {name}, 年龄: {age}, 性别: {gender}")

这样写下来,用到了Python中的unpacking,首先代码行数减少了。
是否真的应用到了unpacking机制,还是说跟变量值交换一样,也是人云亦云,我们可以看下对应的字节码序列:

字节码指令序列的其他指令可以不用关心,我们重点看源码第4行的对应指令序列,可以看到:
1、确实触发了unpacking机制;
2、UNPACK_SEQUENCE指令,用于将栈顶的集合变量进行拆包的操作,拆为多少个,指令有一个操作数,此时是3,由操作数决定;
3、拆包指令实现的结果是,栈顶集合变量出栈,按照操作数拆分,然后依次入栈。

unpacking的机制,看似好用,但是,细心的你,可能立马会发现一个问题,如果集合中元素有很多个,此时,我们只需要其中的一部分,怎么办呢。

解决的方法,就是我们在前面的文章中提到过的占位符_的用法。
比如,我们当前,只需要姓名、性别,可以这样改写:

# unpacking
persons = [('张三', 18, '女'), ('小红', 23, '男')]
for p in persons:
    name, _, gender = p
    print(f"姓名: {name}, 性别: {gender}")

所有我们不需要的元素,都可以用占位符进行舍弃,但是,占位符_只是省去了我们给变量取名的麻烦,不需要的元素比较多的时候,似乎还是不太方便,反而不如索引操作方便,好在Python中提供了对应的解决方案。

扩展的unpacking

的变量,在Python中为可扩展的变量。
如下,为带
的unpacking的写法:

# * unpacking
persons = [('张三', 18, 190, '女'), ('小红', 23, 165, '男')]
for p in persons:
    name, *others, gender = p
    print(others)
    print(type(others))
    print(f"姓名: {name}, 性别: {gender}")

代码中,会将除了name接收的第一个元素,以及gender接收的最后一个元素,之外的所有元素,封装为一个列表,由others接收。
从对应的字节码,可以看出有些不同:

首先,翻译为字节码指令序列时,多了EXTENDED_ARG指令,用于扩展变量others;其次拆包的指令,从之前的UNPACK_SEQUENCE变成了UNPACK_EX。

注意,关于带星号定义的可扩展变量,可以理解为不定长列表,可以接收零个或者多个值,后续在函数的定义中也会用到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1911154.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多模态:Nougat详解

文章目录 前言一、模型结构1. encoder2. decoder3. set 二、数据增强三、数据splitting the pages 四、实验评估repetitions during inference 五、代码1. 环境安装2. Dataset(dataset.py)3. Model(model.py) 总结 前言 科学知识…

【论文速读】| 用于安全漏洞防范的人工智能技术

本次分享论文:Artificial Intelligence Techniques for Security Vulnerability Prevention 基本信息 原文作者:Steve Kommrusch 作者单位:Colorado State University, Department of Computer Science, Fort Collins, CO, 80525 USA 关键…

给数组/对象添加一个(key-value)对象

需要将一个value值前面加上key值,放进数组/对象中 this.$set(res.data[0],type,1) this.$set( target, key, value ) target:要更改的数据源(可以是对象或者数组) key:要更改的具体数据 value :重新赋的值。 结果:…

初识C++【命名空间】【输入输出】【缺省参数】【函数重载】

前言 C是一种通用的编程语言,被广泛用于开发各种应用程序,包括系统软件、游戏、手机应用和高性能计算等。它是C语言的扩展,添加了许多新特性和功能,并支持面向对象编程。C可以在不同的平台上编译和运行,具有高效性、可…

C++:C++入门基础|命名空间|输入输出

欢迎来到HarperLee的学习笔记! 博主主页传送门: HarperLee的博客主页! 想要一起进步的uu来后台哦! 一、什么是C? 在此之前,我们所学习的C语言是一种结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题&a…

【Java算法】二分查找 下

🔥个人主页: 中草药 🔥专栏:【算法工作坊】算法实战揭秘 一.山脉数组的峰顶索引 题目链接:852.山脉数组的峰顶 ​ 算法原理 这段代码实现了一个查找山峰数组中峰值索引的算法。山峰数组是一个先递增后递减的数组&…

14-55 剑和诗人29 - RoSA:一种新的 PEFT 方法

介绍 参数高效微调 (PEFT) 方法已成为 NLP 领域研究的热门领域。随着语言模型不断扩展到前所未有的规模,在下游任务中微调所有参数的成本变得非常高昂。PEFT 方法通过将微调限制在一小部分参数上来提供解决方案,从而以极低的计算成本在自然语言理解任务上…

QT入门看这一篇就够(详解含qt源码)

目录 一、Qt概述 1.1 什么是Qt 1.2 Qt的发展史 1.3 Qt的优势 1.4 Qt版本 1.5 成功案例 二、创建Qt项目 2.1 使用向导创建 2.2 一个最简单的Qt应用程序 2.2.1 main函数中 2.2.2 类头文件 2.3 .pro文件 2.4 命名规范 2.5 QtCreator常用快捷键 三、Qt按钮小程序 …

【技术选型】MySQL、Oracle、Postgresql如何选择

【技术选型】MySQL、Oracle、Postgresql如何选择 开篇词:干货篇:MySQL:Oracle:PostgreSQL: 总结篇:我是杰叔叔,一名沪漂的码农,下期再会! 开篇词: 常见几种关…

Nuxt框架中内置组件详解及使用指南(四)

title: Nuxt框架中内置组件详解及使用指南(四) date: 2024/7/9 updated: 2024/7/9 author: cmdragon excerpt: 摘要:本文详细介绍了Nuxt 3框架中的两个内置组件:和的使用方法与示例。用于捕获并处理客户端错误,提供…

图解HTTP(5、与 HTTP 协作的 Web 服务器 6、HTTP 首部)

5、与 HTTP 协作的 Web 服务器 一台 Web 服务器可搭建多个独立域名的 Web 网站,也可作为通信路径上的中转服务器提升传输效率。 用单台虚拟主机实现多个域名 在相同的 IP 地址下,由于虚拟主机可以寄存多个不同主机名和域名的 Web 网站,因此…

回溯算法-以学生就业管理系统为例

1.回溯算法介绍 1.来源 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。 用回溯算法解决问题的一般步骤: 1、 针对所给问题,定义问题的解空间,它至少包含问题的一个(最优)解。 2 、确定易于搜…

[ios-h5]在ios系统浏览器中输入框得到焦点时页面自动放大

问题&#xff1a; 在ios系统浏览器中输入框得到焦点时页面自动放大。 解决&#xff1a; 添加meta标签。 <meta name"apple-mobile-web-app-capable" content"yes" /> <meta name"viewport" content"widthdevice-width, initial-…

循环练习题

思路&#xff1a; 代码&#xff1a; public static void main(String[] args) {double sum0;for (int i1;i<100;i){if (i%2!0){sum1.0/i;}else {sum-1.0/i;}}System.out.println(sum);} 结果为&#xff1a;

每日一练 - RSTP响应端口故障后的处理流程

01 真题题目 在如图所示的网络中&#xff0c; 所有的交换机运行 RSTP 协议&#xff0c; 假如 SWB 的 E 1 接口故障后&#xff0c; RSTP 的处理过程是&#xff1a;(多选) A.SWB 删除 MAC 地址表中以 E 1 为目的端口的端口表项。 B.重新计算生成树&#xff0c;选举 E2 为新的根…

ER模型理论和三范式

ER模型理论和三范式 各种关系多对一一对一一对多多对多 三范式理论函数依赖完全函数依赖部分函数依赖传递&#xff08;间接&#xff09;函数依赖 第一范式&#xff1a;属性&#xff08;表字段&#xff09;不可切割第二范式&#xff1a;不能存在 部分函数依赖(都存在完全函数依赖…

为什么3d模型在透视里面闪烁?---模大狮模型网

在展览3D模型设计中&#xff0c;透视效果是展示空间深度和立体感的重要手段。然而&#xff0c;有时候我们会面对3D模型在特定透视角度下出现闪烁或者失真的问题。本文将深入探讨这一现象的原因及解决方法&#xff0c;帮助设计师们更好地理解和处理这类挑战。 一、为什么3D模型在…

Maven在Windows中的配置方法

本文介绍在Windows电脑中&#xff0c;下载、配置Maven工具的详细方法。 Maven是一个广泛使用的项目管理工具&#xff0c;主要针对Java项目&#xff0c;但也可以用于其他类型的项目&#xff1b;其由Apache软件基金会维护&#xff0c;旨在简化和标准化项目构建过程&#xff0c;依…

Tomcat的安全配置

1、生产环境优化 2、部分漏洞修复 转载自风险评估&#xff1a;Tomcat的安全配置&#xff0c;Tomcat安全基线检查加固-CSDN博客

SpringBoot实战:轻松实现接口数据脱敏

文章目录 引言一、接口数据脱敏概述1.1 接口数据脱敏的定义1.2 接口数据脱敏的重要性1.3 接口数据脱敏的实现方式 二、开发环境三、实现接口返回数据脱敏3.1 添加依赖3.2 创建自定义注解3.3 定义脱敏枚举类3.4 创建自定义序列化类 四、测试4.1 编写测试代码4.2 测试 五、总结 引…