Python 中星号(*)的用法

这篇具有很好参考价值的文章主要介绍了Python 中星号(*)的用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Python实用教程_spiritx的博客-CSDN博客

星号​​*​​ 往往被称为乘法运算符,是所有程序中最为常用的运算符号之一,在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)) #返回的是True
    for i in args:
        print(i)
fun(1, 2, 3)

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

关键字变参

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

def fun2(**kwargs):
    print(isinstance(kwargs, dict)) #返回的是True
    pass
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 Bai

def 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 reduce

primes = [2, 3, 5, 7, 11, 13]

def product(*numbers):
    p = reduce(lambda x, y: x * y, numbers)
    return p 

product(*primes)
# 30030

product(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 = 6

a, *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 = 6

str1 = 'python'
s1,*s2,s3 = str1
print(s1) #p
print(s2) #['y', 't', 'h', 'o']
print(s3) #n

t = ('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​​ 。文章来源地址https://www.toymoban.com/news/detail-753532.html

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

到了这里,关于Python 中星号(*)的用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python教程:@符号的用法

    @ 符号在 Python 中最常见的使用情况是在装饰器中。一个装饰器可以让你改变一个函数或类的行为。 @ 符号也可以作为一个数学运算符使用,因为它可以在Python中乘以矩阵。本教程将教你如何使用 Python 的@ 符号。 装饰器是一个接受一个函数作为参数的函数,向其添加一些功能

    2024年02月08日
    浏览(34)
  • Python教程:while 循环用法讲解

    1.while 循环 Python 中 while 语句的一般形式: 执行流程图如下: 同样需要注意冒号和缩进。另外,在 Python 中没有 do…while 循环。 以下实例使用了 while 来计算 1 到 100 的总和: 执行结果: 2.无限循环 我们可以通过设置条件表达式永远不为 false 来实现无限循环,实例如下: 执

    2023年04月15日
    浏览(41)
  • Python教程(9)——Python变量类型列表list的用法介绍

    在Python中,列表(list)是一种有序、可变的数据结构,用于存储多个元素。列表可以包含不同类型的元素,包括整数、浮点数、字符串等。实际上列表有点类似C++语言中的数组,但仅仅只是类似,和数组还是有点不一样的。列表非常适合利用顺序和位置定位某一元素,尤其是

    2024年02月13日
    浏览(42)
  • Python教程(11)——Python中的字典dict的用法介绍

    列表虽然好,但是如果需要快速的数据查找,就必须进行需要遍历,也就是最坏情况需要遍历完一遍才能找到需要的那个数据,时间复杂度是O(n),显然这个速度是很难接受的,于是就必须要有新的数据结构出现,于是字典就诞生了! 在Python中,字典(Dictionary)是一种无序的

    2024年02月10日
    浏览(43)
  • 在Python环境中运行R语言的配环境实用教程

    前情提要 在做一些生物信息与医学统计的工作,本来偷懒希望只靠python完成的,结果还是需要用R语言,倒腾了一会儿,调成功了,就记录一下这个过程。 我的环境: win10, pycharm, R-4.3.2 首先,我们安装R语言,这里给出两个链接 官网:R: The R Project for Statistical Computing 清华镜像

    2024年01月23日
    浏览(37)
  • python基础教程:re模块用法详解

    前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 一、正则表达式的特殊字符介绍 正则表达式 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ 素材、视频教程、完整代码、插件安装教程我都准备好了,直接在文末名片自取就可 二、re模块的方法介绍 1、匹配类方

    2024年02月11日
    浏览(40)
  • Python教程(10)——Python变量类型元组tuple的详细用法

    在Python中,元组(Tuple)是一种有序且不可变的数据类型。元组可以包含任意数量的元素,用逗号分隔,并用圆括号括起来。与列表(List)不同,元组的元素不能修改。元组与列表一样,可以通过索引访问其中的元素。 元组的不可变性意味着无法向元组中添加、删除或修改元

    2024年02月12日
    浏览(33)
  • Pytorch实用教程:Pytorch中torch.max的用法

    torch.max 在 PyTorch 中是一个非常有用的函数,它可以用于多种场景,包括寻找张量中的最大值、沿指定维度进行最大值操作,并且还可以返回最大值的索引。其用法可以根据你的需求进行不同的调用方式。 基本用法 找到整个张量的最大值 如果直接对一个张量使用 torch.max ,它

    2024年04月13日
    浏览(33)
  • Python入门教程23:math模块的用法

    **math是Python 的一个内置模块,它提供了许多数学函数和常量,用于进行数学计算。**以下是一些常用的math模块中的函数和常量: math.pi:圆周率π的近似值,约等于3.14159。 math.e:自然对数的底数e的近似值,约等于2.71828。 math.sqrt(x):求平方根。 math.pow(x, y):求x的y次方。 ma

    2024年02月12日
    浏览(41)
  • Python入门教程+项目实战-14.1节-函数的参数用法

    目录 14.2.1 位置参数与参数 14.2.2 函数的参数默认值 14.2.3 函数的引用类型参数 14.2.4 函数的可变参数 14.2.5 知识要点 14.2.6 系统学习python 位置参数与参数的位置相关,这里的位置是指定义函数时的从左到右的参数排列顺序。在调用函数时,会自动将实参与形参的位置对

    2024年02月11日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包