Python 中星号(*)的用法

星号​​*​​ 往往被称为乘法运算符,是所有程序中最为常用的运算符号之一,在Python 中,星号还有很多隐藏的强大功能。 本文将用最容易理解的例子来解释星号*的 五个使用场景,从初级用法到高阶用法。

乘法和幂运算符

最简单的用法是利用星号作为基本的运算符:

单个 ​​*​​​ 用于乘法运算;如果是列表,则是复制n次

两个 ​​​** ​​ 表示幂运算

>>> 2*3
>>> 6
>>> 2**3
>>> 8

重复容器内容

Python也支持类列表的容器类对象(即序列)与整数相乘,即为按照整数实现重复其中的元素数量。

>>> 'star' * 2
starstar
>>> ['star'] * 2
['star', 'star’]
zeros_list = [0] * 10
print(zeros_list) #[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
zeros_tuple = (0,) * 10
print(zeros_tuple) #(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
vector_list = [[1, 2, 3]] * 3
print(vector_list) #[[1, 2, 3], [1, 2, 3], [1, 2, 3]]

 

函数变参声明

一般来说,函数往往接收固定数量的参数;但是如果我们需要更大的灵活性,比如当不确定将传递多少个参数时,此时将是星号​​*​​ 发挥作用的时候。

在Python中有两类参数,一类是位置参数,另外一类是关键词参数,前者根据位置确定相应值,后者则是依据参数名称确定。

位置变参

*args可以收集任意个数的位置参数,星号是必须要的,args可以是任意的变量名:

def fun(*args):print(isinstance(args, tuple)) #返回的是Truefor i in args:print(i)
fun(1, 2, 3)

上面的例子表示,我们虽然传递了3个参数1, 2, 3,但是fun函数把他们放到了一个元组。并且参数的个数不限。

关键字变参

 **kwargs可以收集任意数量的按名参数/关键字参数,**是必须要的,kwargs可以是任意变量名:

def fun2(**kwargs):print(isinstance(kwargs, dict)) #返回的是Truepass
fun2(a=1, b=2, c=3)

上面的例子表明,使用两个星号,我们传递的参数是被当作一个字典来进行传递的,参数的个数不限。其实我们看kwargs这个名字就可以推出,这个参数是字典类型的。 

def print_genius(*names):print(type(names))for n in names:print(n)print_genius('Elon Mask', 'Du Fu ', 'Li Bai')
# <class 'tuple'>
# Elon Mask
# Du Fu 
# Li Baidef top_genius(**names):print(type(names))for k, v in names.items():print(k, v)top_genius(Top1="Elon Mask", Top2="Du Fu", Top3="Li Bai")
# <class 'dict'>
# Top1 Elon Mask
# Top2 Du Fu
# Top3 Li Bai

如上例所示,在定义函数时,我们可以定义一个以一个或两个星号为前缀的参数,以捕获不限制数量的参数输入。

总结如下:

  • 以 一个 ​​* ​​ 为前缀的参数可以将任意数量的参数以元组形式传入
  • 以两个 ​​**​​ 为前缀的参数可以将任意数量的参数以字典形式传入

任意变参

按照惯例,当我们定义的函数接收不定数量的参数时,我们一般采用以下函数定义形式:

def foo(*args, **kwargs):pass

注意:位置参数一定要放在关键字参数之前,下面这个声明是错误的

def save_ranking(**kwargs, *args):...

 

限制仅为关键字变参

星号​​* ​​的一个非常酷的用法是使函数只能接收关键字参数。

def genius(*, first_name, last_name):print(first_name, last_name)# genius('Li','Bai')
# TypeError: genius() takes 0 positional arguments but 2 were given
genius(first_name='Li', last_name='Bai')
# Li Bai

上述代码采用了星号​​* ​​限制了星号之后的参数必须采用关键字形式来调用上述函数。 实际上,如果我们只是想将一些参数限制为仅以关键字形式输入同时另一部分参数依旧按照位置形式输入,此时我们可以将位置参数放置在星号之前。

def genius(age, *, first_name, last_name):print(first_name, last_name, 'is', age)
genius(28, first_name='Li', last_name='Bai')
# Li Bai is 28

如果我们想强制只使用位置参数,使用 / 号来实现

def only_positional_arguments(arg1, arg2, /):pass

 如果你传递关键字参数,会发生报错

only_positional_arguments(arg1=1, arg2=2)"""
TypeError: only_positional_arguments() got some positional-only arguments passed as keyword arguments: 'arg1, arg2'
"""

 

函数参数拆解

我们可以使用星号​​* ​​来解包可迭代对象,可以很优雅的进行参数传递。

位置参数拆解

调用函数时,在输入参数前添加星号 * 可以对参数执行提取操作,比如对列表、元组、字符串等迭代类型的输入参数做提取之后,迭代类型的数据元素会被逐个取出。

print('list', sep=',')
print(*'list', sep=',')
print(['hello', 'world', '!'], sep=',')
print(*['hello', 'world', '!'], sep=',’)‘’'
list
l,i,s,t
['hello', 'world', '!']
hello,world,!
‘''

 *号将字符串、列表、元组等进行拆解,作为位置参数传递给函数,函数要求能接收这些位置参数(函数的参数个数与拆解后的元素个数相等,或者可以接受位置变参)

def fun(a, b, c):return a+b+c
test = [1, 2, 3]
print(fun(*test))
#把序列test中的每个元素,当作位置参数传递到函数中去,就不用test[0],test[1]这样了

 再例如:

from functools import reduceprimes = [2, 3, 5, 7, 11, 13]def product(*numbers):p = reduce(lambda x, y: x * y, numbers)return p product(*primes)
# 30030product(primes)
# [2, 3, 5, 7, 11, 13]

因为product()能接收任意参数,我们本来需要将列表中的元素取出来,然后传给此函数。但在这里,如果以*primes的方式向函数提供primes列表数据,则primes所引用的列表会被解包,其中的每个素数都被传给函数,并被收集后用变量numbers引用。如果传该列表primes给函数,就不能解包,numbers所引用的元组中只有一个primes列表。

关键字参数拆解

 在字典类型数据前添加两个星号 **,对字典数据执行提取,然后以关键字参数的形式输入函数。

def fun(c, b, a):#注意顺序return a==1 and b==2 and c==3
test = {'a':1, 'b':2, 'c':3}
print(fun(**test))
def foobar(param1=None, param4=None):return "{}{}".format(param4, param1)values = {"param1": "foo", "param4": "bar"}print(foobar(**values)) #barfoo

虽然字典中的定义的数据和函数定义的顺序不一致,但是我们是按照关键字来进行函数赋值的,所以这个函数返回的结构是True

使用两个星号实际是对字典进行解包操作。

headers = {'Accept': 'text/plain','Content-Length': 348, 'Host': 'http://mingrammer.com' 
}  def pre_process(**headers): content_length = headers['Content-Length'] print('content length: ', content_length) host = headers['Host']if 'https' not in host: raise ValueError('You must use SSL for http communication')  pre_process(**headers)
# content length:  348
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 7, in pre_process
# ValueError: You must use SSL for http communication

赋值变量解包

部分列表赋值

在给*valuename进行赋值时,会自动将一个列表、元组、字符串赋值给valuename,对于前后的其他变量,解释器将给它们单独赋值,特别注意的,如果只有一个*变量,需要写上逗号,表示它是一个列表在接收赋值。

无论原来的类型是什么类型,valuename赋值后都是列表类型

numbers = [1, 2, 3, 4, 5, 6]
# The left side of unpacking should be list or tuple.
*a, = numbers #直接写成*a会提示语法错误
print(a) ## a = [1, 2, 3, 4, 5, 6]*a, b = numbers
print(a) # a = [1, 2, 3, 4, 5]
print(b) # b = 6a, *b, = numbers
print(a) # a = 1
print(b) # b = [2, 3, 4, 5, 6]a, *b, c = numbers
print(a) # a = 1
print(b) # b = [2, 3, 4, 5]
print(c) # c = 6str1 = 'python'
s1,*s2,s3 = str1
print(s1) #p
print(s2) #['y', 't', 'h', 'o']
print(s3) #nt = ('a', 'b', 'c', 'd', 'e')
t1,*t2,t3 = t
print(t1) #a
print(t2) #['b', 'c', 'd']
print(t3) #c

列表解包连接

 可以通过*号先将列表解包,然后在通过括号将元素重新组织起来:

A = [1, 2, 3]
B = (4, 5, 6)
C = {7, 8, 9}
L = [*A, *B, *C]
print(L)
# [1, 2, 3, 4, 5, 6, 8, 9, 7]A = ('1', '2', '3')
B = ('a', 'b', 'c')
C = {*A, *B}
print(C) #{'a', '1', 'c', 'b', '2', '3'}

甚至在连接的过程中还可以加入其他的值: 

my_list_1 = [1, 2, 3]
my_list_2 = [10, 20, 30]
num= 'union'
merged_list = [*my_list_1, num, *my_list_2]
print(merged_list) #[1, 2, 3, 'union', 10, 20, 30]

字典解包连接

两个星号可以针对字典类型进行解包

dict1 = {'age': '22','country': 'BEIJING'
}dict2 = {'email': 'blog@example.com'
}user_dict = {'username': 'kanye', **dict1, **dict2}
print(user_dict)
#{'username': 'kanye', 'age': '22', 'country': 'BEIJING', 'email': 'blog@example.com'}

可以通过多种方式合并两个字典

>>> x = {'a': 1, 'b': 2}
>>> y = {'a': 10, 'c': 30}
>>> yy = {'aa': 10, 'c': 30}
>>> z = x | y  # Union operator introduced recently
>>> z
{'a': 10, 'b': 2, 'c': 30}
>>> x.update(y)  # in place update
# as `y` value getting updated in `x`, `a` value getting overwritten from 1 to 10.
>>> x
{'a': 10, 'b': 2, 'c': 30}
>>> z = dict(**x, **yy)
>>> z
{'a': 1, 'b': 2, 'aa': 10, 'c': 30}
# same key in two dictionaries will throw error
>>> z = dict(**x, **y)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: dict() got multiple values for keyword argument 'a'

如果我们利用一个​​*​​​作为​​dict​​​ 的前缀,它的​​key​​​ 将被解包;如果我们使用双星号​​**​​​ 作为前缀,其​​value​​​ 将被解包;此时我们必须显示使用​​key​​​ 来接收解包后的​​value​​ 。

D = {'first': 1, 'second': 2, 'third': 3}print(*D)
# first second third# print(**D)
# TypeError: 'first' is an invalid keyword argument for print()print('{first},{second},{third}'.format(**D))
# 1,2,3

 

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

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

相关文章

计算机竞赛 基于大数据的股票量化分析与股价预测系统

文章目录 0 前言1 课题背景2 实现效果3 设计原理QTChartsarma模型预测K-means聚类算法算法实现关键问题说明 4 部分核心代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于大数据的股票量化分析与股价预测系统 该项目较为新颖…

GMP原理与调度

GMP原理和调度 1.Golang"调度器"的由来1.1单进程时代不需要调度器1.2多进程/线程时代有了调度器需求1.3协程来提高cpu利用率 1.Golang"调度器"的由来 1.1单进程时代不需要调度器 早期的操作系统每个程序就是一个进程&#xff0c;直到一个程序运行完毕&am…

pandas由入门到精通-数据透视表

采集的数据存储后通常会分为多个文件或数据库,如何将这些文件按需拼接,或按键进行连接十分重要。这节将介绍数据索引的复杂操作如分层索引,stack,unstack,seet_index,reset_index等帮助重构数据,数据的拼接如merge,join,concat,combine_first等帮助连接数据,以及数据透视表…

1.7 【MySQL】常用存储引擎

MySQL 支持非常多种存储引擎&#xff0c;我这先列举一些&#xff1a; 存储引擎 描述 ARCHIVE 用于数据存档&#xff08;行被插入后不能再修改&#xff09; BLACKHOLE 丢弃写操作&#xff0c;读操作会返回空内容 CSV 在存储数据时&#xff0c;以逗号分隔各个数据项 FEDE…

微信小程序发布迭代版本后如何提示用户强制更新新版本

在点击小程序发布的时候选择&#xff0c;升级选项 之前用户使用过的再打开小程序页面就会弹出升级弹窗modal

ide-eval-resetter jar包下载、源码、使用介绍

如果你在找ide-eval-resetter插件&#xff0c;这里告诉你&#xff0c;2021.3版本开始该插件正式失效。 如果你安装的JB产品版本低于2021.3版本&#xff0c;你确定要找ide-eval-resetter&#xff0c;下面提供相关链接希望对你有帮助。 ide-eval-resetter源码&#xff1a; Githu…

深度学习9:简单理解生成对抗网络原理

目录 生成算法 生成对抗网络&#xff08;GAN&#xff09; “生成”部分 “对抗性”部分 GAN如何运作&#xff1f; 培训GAN的技巧&#xff1f; GAN代码示例 如何改善GAN&#xff1f; 结论 生成算法 您可以将生成算法分组到三个桶中的一个&#xff1a; 鉴于标签&#…

华为OD机试真题【最大利润】

1、题目描述 【最大利润】 商人经营一家店铺&#xff0c;有number种商品&#xff0c;由于仓库限制每件商品的最大持有数量是item[index] 每种商品的价格是item-price[item_index][day] 通过对商品的买进和卖出获取利润 请给出商人在days天内能获取的最大的利润 注&#xff1a;…

C++—纯虚函数

一、前言 定义一个函数为虚函数&#xff0c;不代表函数为不被实现的函数。 定义函数为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数&#xff0c;才代表函数没有被实现。 定义纯虚函数是为了实现一个接口&#xff0c;起到一个规范的作用&…

VUE3 Setup语法糖

目前setup sugar已经进行了定稿&#xff0c;vue3 setup sugar TS的写法看起来很香,写本文时 Vue 版本是 “^3.2.6” script setup 语法糖 新的 setup 选项是在组件创建之前, props 被解析之后执行&#xff0c;是组合式 API 的入口。 WARNING 在 setup 中你应该避免使用 thi…

火山引擎 DataLeap:从短视频 APP 实践看如何统一数据指标口径

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 短视频正在成为越来越多人发现世界的窗口&#xff0c;其背后的创作者生态建设是各大短视频 APP 不可忽视的重要组成部分。 为了激励更多优质内容生产&#xff0c;某…

数据压缩算法一览

文章首发地址 Huffman编码&#xff1a; Huffman编码是一种基于字符频率的无损压缩算法。它将出现频率较高的字符用较短的编码表示&#xff0c;出现频率较低的字符用较长的编码表示&#xff0c;从而实现压缩。Lempel-Ziv-Welch (LZW)&#xff1a; LZW是一种基于字典的无损压缩算…

iOS 分别对一张图的局部进行磨砂,拼接起来不能贴合

效果图 需求&#xff0c;由于视图层级的原因&#xff0c;需要对图片分开进行磨砂&#xff0c; 然后组合在一起 如图&#xff0c;上下两部分&#xff0c;上下两个UIImageVIew大小相同&#xff0c;都是和图片同样的大小&#xff0c;只是上面的UIimageVIew 只展示上半部份 &#…

初识【类和对象】

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 4.类的访问限定符及封装 5.类的作用域 6.类的实例化 7.类的对象大小的计算 8.类成员函数的this指针 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的…

stm32之9.中断优先级配置

主函数main.c #include <stm32f4xx.h> #include "led.h" #include "key.h"#define PAin(n) (*(volatile uint32_t *)(0x42000000 (GPIOA_BASE0x10-0x40000000)*32 (n)*4)) #define PEin(n) (*(volatile uint32_t *)(0x42000000 (GP…

html实现iframe全屏

前言 html浏览器全屏操作&#xff0c;基于jquery iframe全屏、指定标签全屏 实现 css /** 全屏*/ .lay-dbclick-box{position: relative;width: 100%;height: 100%; } .lay-dbclick-screen{position: absolute;top: 0;left: 0;width: 100%;height: 100%;z-index: 999999999…

pytorch里面的nn.AdaptiveAvgPool2d

今天遇到nn.AdaptiveAvgPool2d((None, 1)) AdaptiveAvgPool2d函数详细解释&#xff1a; 2D自适应平均池化&#xff08;2D adaptive average pooling&#xff09;是一种对输入信号进行二维平均池化的操作&#xff0c;输入信号由多个输入平面&#xff08;input planes&#xff0…

分布式技术

分布式没有权威的技术&#xff0c;只有实践经验和积累的组件。常见的分布式技术有发号机制、分布式数据库、分布式数据库事物、基于Redis的分布式缓存、分布式会话、分布式安全认证。 1、发号机制 在数据库&#xff08;关系数据库&#xff09;中&#xff0c;主键往往是一条记…

为什么学嵌入式还要学单片机和人工智能?

从企业用人需求的角度来看&#xff0c;许多企业在招聘嵌入式工程师时都希望其具备一定的技能要求。其中&#xff0c;熟悉STM32单片机开发、熟悉嵌入式Linux开发以及熟悉实时操作系统开发&#xff0c;如FreeRTOS等&#xff0c;是常见的要求。掌握这些技术点的课程将为学生提供更…

成都国际车展来袭:有颜值有实力 大运新能源两款车型备受关注

今年成都国际车展现场最大看点是什么&#xff1f;诸多实力车企汇聚一堂各显神通&#xff0c;形式各样的新能源车型更是吸晴无数&#xff0c;成为消费者的购车首选。老品牌、新势力的大运新能源独具匠心设计特色展台&#xff0c;旗下两款车型悦虎和远志M1重磅登场。两款车型既有…