理解 python 中的* 打包和解包

注意, 本文的打包和解包的概念有点类似与java 的装箱和解箱

但是还是有点区别
java 中的装箱指的是 把一系列的值让放入1个对象的属性中

而python的打包概念 包括

  1. 把一组元素打包成1个list or tuple
  2. 把一系列 key value pair 打包成1个dict




Python * 的基本功能, 乘法

* 首先是1个人乘法符号 例如

from loguru import loggerdef process():logger.info(3 * 12) # 36logger.info("hello" * 3) # hellohellohellologger.info([1, 2, 3] * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]logger.info(["a", "b", "c"] * 3) # ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']logger.info("hello" * "world") # TypeError: can't multiply sequence by non-int of type 'str'if __name__ == "__main__":import src.configs.configprocess()

直接的注意的是, * 的乘法不单止 数字乘数字
还包括字符串 乘 整数, 数组乘整数
但是不support string * string , string * float , string * 数组, 数组 * 数组等




* 的打包功能

第1个例子
def sample1():list_num = [1, 2, 3]first, second, rest = list_numlogger.info("first is {}".format(first)) # 1logger.info("second is {}".format(second)) # 2    logger.info("rest is {}".format(rest)) # 3

上面的例子就是一个简单的解包例子
我们用3个变量去接受1个3个元素的数组是可以正常给3个变量赋值的

2024-05-05 23:53:25.407 | INFO     | __main__:sample1:6 - first is 1
2024-05-05 23:53:25.407 | INFO     | __main__:sample1:7 - second is 2
2024-05-05 23:53:25.407 | INFO     | __main__:sample1:8 - rest is 3
第2个例子

这时如果我改写成让3个变量去接受6个元素的数组
是会报错的

def sample2():list_num = [1, 2, 3, 4, 5, 6, 7]first, second, rest = list_numlogger.info("first is {}".format(first)) # 1logger.info("second is {}".format(second)) # 2    logger.info("rest is {}".format(rest)) # too many values to unpack (expected 3)

错误

  File "/home/gateman/Projects/python/python_common_import/src/pack_unpack/star_pack.py", line 5, in sample1first, second, rest = list_num^^^^^^^^^^^^^^^^^^^
ValueError: too many values to unpack (expected 3)
第3个例子

这时我们可以用*rest 去接受剩下的元素, 这时的rest 就是1个数组, 完成了打包的功能

def sample3():list_num = [1, 2, 3, 4, 5, 6, 7]first, second, *rest = list_numlogger.info("first is {}".format(first)) # 1logger.info("second is {}".format(second)) # 2    logger.info("rest is {}".format(rest)) # [3, 4, 5, 6, 7]

输出

2024-05-06 00:01:58.114 | INFO     | __main__:sample3:13 - first is 1
2024-05-06 00:01:58.114 | INFO     | __main__:sample3:14 - second is 2
2024-05-06 00:01:58.114 | INFO     | __main__:sample3:15 - rest is [3, 4, 5, 6, 7]

还有, 尝试打包两个变量是不允许的

first, second, *rest, *rest2 = list_num # Only one unpack operation allowed in listPylance  
第4个例子

*打包功能最常用的场景 *args (类似于java 的可变参数 String… strings)

def sample4():print_list([1, 2, 3])print_list2(1, 2, 3)def print_list(list_num):for i in list_num:logger.info(i)def print_list2(*list_num):for i in list_num:logger.info(i)if __name__ == "__main__":import src.configs.configsample4()

输出

2024-05-06 00:18:04.939 | INFO     | __main__:print_list:31 - 1
2024-05-06 00:18:04.939 | INFO     | __main__:print_list:31 - 2
2024-05-06 00:18:04.939 | INFO     | __main__:print_list:31 - 3
2024-05-06 00:18:04.939 | INFO     | __main__:print_list2:35 - 1
2024-05-06 00:18:04.939 | INFO     | __main__:print_list2:35 - 2
2024-05-06 00:18:04.940 | INFO     | __main__:print_list2:35 - 3

上面定义了两个输出数组的函数
其中print_list1 接受的1个是普通的数组对象

而print_list2 接受的是多个元素, 而且是可以动态打包到 args 变量的
这就是我们常见到的
def func(*args) *args的意思, 自动把传入的动态多个元素参数 打包称1个数组参数




** 的打包功能 - 打包key value pair 到字典

def sample5():print_value("abc", 2, 3, a=4,b=5)def print_value(*args, **kwargs):for i in range(len(args)):logger.info("args[{}] is {}".format(i, args[i]))for key in kwargs:logger.info("kwargs[{}] is {}".format(key, kwargs[key]))if __name__ == "__main__":import src.configs.configsample5()

这个例子中, print_value的参数 是 *args, **kwargs

意思是除了用*args 接受所有的值类型参数(注意上面的例子是string 和 int 参数混合传入的), 还可以用**kwargs来接受剩余的 key value pair 参数, 方便!

输出:

2024-05-06 00:31:33.215 | INFO     | __main__:print_value:44 - args[0] is abc
2024-05-06 00:31:33.216 | INFO     | __main__:print_value:44 - args[1] is 2
2024-05-06 00:31:33.216 | INFO     | __main__:print_value:44 - args[2] is 3
2024-05-06 00:31:33.216 | INFO     | __main__:print_value:46 - kwargs[a] is 4
2024-05-06 00:31:33.216 | INFO     | __main__:print_value:46 - kwargs[b] is 5





C
现在讲到解包了

第一个例子:
def sample1():person_list = ["Jay", 2]# print_value(person_list) # error print_value() missing 1 required positional argument: 'age'print_value(*person_list)person_dict = {"name": "Jade", "age": 3}# person_dict = {"firstname": "Jade", "age": 3} # error print_value() got an unexpected keyword argument 'firstname'print_value(**person_dict)def print_value(name, age):logger.info("name is {}".format(name))logger.info("age is {}".format(age))if __name__ == "__main__":import src.configs.configsample1()

上面定义了1个普通 print_value() 里面有两个参数
如果直接把数组 person_list 传入肯定是报错的
但是这时可以用 person_list 解包成多个 元素, 所以用person_list 传入是ok的

同样地, **person_dict , 双星可以为dict 对象解包, 但是对象的属性必须等于参数定义的参数名字!

第2个例子

解包同样常见于list/tuple/dict 合并

def sample2():list = [1, 2, 3]tuple = (4, 5, 6)tuple2 = (*list, *tuple)logger.info(tuple2) # (1, 2, 3, 4, 5, 6)dict1 = {"name": "Jay", "age": 2}dict2 = {"weight": 20, "height": 85}dict3 = {**dict1, **dict2}logger.info(dict3) # {'name': 'Jay', 'age': 2, 'weight': 20, 'height': 85}if __name__ == "__main__":import src.configs.configsample2()

是不是很方便?
注意的是 list 和 tuple 可以互相合并

但是list 和 tuple 都不能和dict 合并




Python 打包和 解包的常用使用情景

打包:
1. 获取从动态多个参数称list/tuple or dict

解包:
2. 把list/tuple or dict 传入 接受普通值参数的函数
3. 合并容器

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

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

相关文章

Mac基于Docker-ubuntu构建c/c++编译环境

编译环境安装和使用被充分验证,如有期望补充的内容欢迎留言评论。 目录 前言 Docker desktop下载安装 修改镜像源 选择ubuntu镜像 docker容器启动 参数说明: 宿主机与docker容器文件共享 宿主机与docker容器拷贝文件 为 Ubuntu 配置 ssh、vim、make 相关工…

Flyway使用教程

Flyway使用教程 背景: 在开发环境对多个不同版本的分支进行开发,如果此时涉及到多张表结构修改(比如新增字段),而在测试环境时却忘了整理SQL 脚本给测试人员执行,就会导致出现 bug,从而影响测试…

Android selinux权限

一.SE 概述 SELinux 是由美国NSA(国安局)和 SCC 开发的 Linux的一个扩张强制访问控制安全模块。原先是在Fluke上开发的,2000年以 GNU GPL 发布。从 fedora core 2开始, 2.6内核的版本都支持SELinux。 在 SELinux 出现之前&#…

神经网络模型里面权重衰减的理解

概述 神经网络模型里面,如果少部分参数的绝对值相对其他值过大,就会造成模型过度依赖于某些特征(由这些较大值所代表),从而更容易产生过拟合问题。因而,我们有必要针对权重设置一种衰减措施,避…

PHP ASCII码的字符串用mb_convert_encoding 转utf-8之后不生效

检测数据类型是ascii,转码之后再检测还是utf-8没生效 private function toUTF8($str){$encode mb_detect_encoding($str, array("ASCII",UTF-8,"GB2312","GBK",BIG5,LATIN1));if ($encode ! UTF-8) {$str1 mb_convert_encoding($str, UTF-8, …

个人银行账户管理程序(2)

在(1)的基础上进行改进 1:增加一个静态成员函数total,记录账户总金额和静态成员函数getTotal 2对不需要改变的对象进行const修饰 3多文件实现 account。h文件 #ifndef _ACCOUNT_ #define _ACCOUNT_ class SavingAccount {pri…

力扣经典150题第五十三题:基本计算器

目录 力扣经典150题第五十六题:基本计算器示例提示解题思路 力扣经典150题第五十六题:基本计算器 给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。 注意:不允许使用任何将字符串作为数学表达式计算的内置函数&#xf…

C#中环境变量

环境变量 什么是环境变量Environment.GetEnvironmentVariable 用于获取指定环境变量的值怎么知道环境变量存不存在?不存在怎么创建? 什么是环境变量 环境变量是操作系统中存储的一种机制,用于保存与操作系统环境和应用程序运行相关的配置信息…

HTML 建立列表——列表标签

HTML 建立列表——列表标签 建立和使用列表 定义列表 <dl></dl>列表标签定义列表; <dt>定义列表标题; <dd>定义列表内容; 说明: 1. dt和dd对应着的, 一个dt可以对应着多个dd; 2. dd完全是为了dt服务的, 对标题进行描述; 实例: <dl> <…

NPM 基础

介绍 npm 是 JavaScript 编程语言的一个包管理器&#xff0c;它允许开发者安装、共享和管理依赖项。npm 与 Node.js 紧密集成&#xff0c;是 Node.js 生态系统中不可或缺的一部分。它提供了一个命令行工具&#xff0c;使得开发者能够轻松地安装、配置和管理项目所需的各种包。…

抓包证书安装到安卓7.0+手机

前言: 首先理解一下,这个不只是证书到浏览器,而是抓包证书到安卓7.0+手机上的文章; 还有一点区分,在浏览器上装的证书,只是让抓包工具可以抓取手机浏览器的包,而不是抓取手机app上的包; 如果你的证书只是简单的在浏览器下进行安装,那么你的手机app是走不了代理网络的…

【微服务】服务保护(通过Sentinel解决雪崩问题)

Sentinel解决雪崩问题 雪崩问题服务保护方案服务降级保护 服务保护技术SentinelFallback服务熔断 雪崩问题 在微服务调用链中如果有一个服务的问题导致整条链上的服务都不可用&#xff0c;称为雪崩 原因 微服务之间的相互调用&#xff0c;服务提供者出现故障服务的消费者没有…

【微服务】配置管理

Nacos配置管理 配置管理配置共享配置热更新 配置管理 将微服务集群中常用&#xff0c;经常变化的配置都写到一个独立的配置文件微服务中进行统一管理 配置共享 在Nacos的界面当中进行配置管理&#xff0c;在配置列表中添加配置 比如各个服务中的jdbc的连接配置&#xff1a; …

HTML/CSS1

1.前置说明 请点这里 2.img元素 格式&#xff1a; <img src"图片地址" alt"占位文字" width"图片宽度" height"图片高度">其中alt是当图片加载失败时显示的文字 而且不同内核的浏览器显示出来的占位文字的效果也是不尽相同的…

linux修改max user processes/file limits

1、修改普通用户单个用户可同时运行的最大进程数 &#xff08;默认为 4096 &#xff09; [rootxxx devops]# cat /etc/security/limits.d/20-nproc.conf # Default limit for number of users processes to prevent # accidental fork bombs. # See rhbz #432903 for reasoni…

【Android学习】简单的登录页面和业务逻辑实现

实现功能 1 登录页&#xff1a;密码登录和验证码登录 2 忘记密码页&#xff1a;修改密码 3 页面基础逻辑 java代码 基础页面 XML login_main.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.and…

游戏后端开发初体验(一)

时间过得很快&#xff0c;一转眼&#xff0c;4月已然过去&#xff0c;迎来了5月。我也完成了第一个月的工作。五一假期没有出游计划&#xff0c;于是想趁这个机会&#xff0c;写下这个月的工作感想&#xff0c;也算是践行“记录即最好的回忆”。 工作环境和日常琐事 公司位于…

Servlet_JSP

1.一些回顾 对于Tomcat部署中 我们有一些补充的点需要在此说明一下 1.如果我们想要查询MINEType的话 可以到TOMCAT_HOME/conf/web.xml中进行查询 里面记录了不同类型对应的MINEType 2.我们客户端发送请求数据给服务器之后 服务器会调用父类中的service方法 然后在内部决定调用…

CMakeLists.txt语法规则:while 循环

一. 简介 前面几篇文章学习了 CMakeLists.txt语法中的一种循环写法&#xff0c;文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;foreach 循环基本用法-CSDN博客 CMakeLists.txt语法规则&#xff1a;foreach循环的关键字-CSDN博客 本文学习 while循环写法。 二. …

Day08-JavaWeb开发-MySQL(多表查询内外连接子查询事务索引)Mybatis入门

1. MySQL多表查询 1.1 概述 1.2 内连接 -- 内连接 -- A. 查询员工的姓名, 及所属的部门名称(隐式内连接实现) select tb_emp.name, tb_dept.name from tb_emp,tb_dept where tb_emp.dept_id tb_dept.id;-- 起别名 select * from tb_emp e, tb_dept d where e.dept_id d.id…