前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >星号的作用

星号的作用

作者头像
老齐
发布于 2021-10-21 09:02:42
发布于 2021-10-21 09:02:42
5.1K00
代码可运行
举报
文章被收录于专栏:老齐教室老齐教室
运行总次数:0
代码可运行

7.2 星号的作用

注: 本文是正在编写的一本书的书稿选登。


星号( * )已经在此前的学习中出现过,它可以作为乘法和乘方的运算符,也可以表示序列中元素的重复。对于函数而言,它的作用则体现在收集参数上。

7.2.1 收集参数

如果函数的参数个数是确定的,就用7.1节中的方式定义函数,但这个假设并不总成立。例如写一个计算人体一天所摄入能量的函数,参数为这一天所吃的东西,显然每一天所吃的食物的种类数并不都一样,即不能确定要提供多少个参数。这种情况下,就要“收集参数”。

1. 收集位置参数

定义函数时,参数前用一个星号( * )表示收集位置参数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> def computer_language(*lang):
...     print(lang)
...
>>> computer_language('python', 'java', 'rust', 'php')
('python', 'java', 'rust', 'php')
>>> computer_language('pascal', 'python')
('pascal', 'python')

函数 computer_language() 的参数 lang 前面有一个星号,当调用此函数时,可以输入任意多个位置参数——实参,这些参数都被收集到一个元组中,并被变量 lang 引用。

还可以这样:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> def computer_language(lang, *others):
...     print(f"lang={lang}")
...     print(f"others = {others}")
...
>>> computer_language('python', 'php', 'c#')     # (1)
lang=python
others = ('php', 'c#')

函数 computer_language() 的形参由两部分组成,lang 同之前的参数含义,*others 则表示用 others 收集其余的实参。从注释(1)的调用中可知,lang 对应第一个对象 'python' ,其余对象则被收集到元组中,并被 others 引用。

下面编写一个函数,用它来挑选诸多数字中的质数(第6章6.6节曾编写了一个关于质数的程序,此处则使用另外一种判断质数的方法)。“诸多”表明个数不确定——当然,可以放到序列中循环,一个一个地判断。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#coding:utf-8
'''
filename: choiceprime.py
'''
import math

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(math.sqrt(n))+1):
        if n % i == 0:
            return False
    return True

def choice(*args):
    return [i for i in args if is_prime(i)]

if __name__ == "__main__":
    prime_number = choice(1,3,5,7,9,11,13,15,17,19,21,23)
    print(prime_number)

函数 is_prime() 用于判断一个自然数是否为质数,参数的个数很明确(此函数的数学原理,请读者自行解决,此处不赘述)。函数 choice() 用于从若干个自然数中选择质数,备选的自然数的个数不确定,故使用 *args 收集参数。

执行程序,结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
% python choiceprime.py 
[3, 5, 7, 11, 13, 17, 19, 23]

2. 收集关键词参数

对于关键词参数,可以使用两个星号 **kwargs 的形式收集。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> def foo(**kwargs):
...     print(kwargs)
...
>>> foo(name='laoqi', age=30)
{'name': 'laoqi', 'age': 30}
>>> foo(a=1, b=2, c=3)
{'a': 1, 'b': 2, 'c': 3}

对于函数 foo() ,不论传入多少个关键词参数,均能收集为一个字典类对象——关键词参数创建了变量与对象的对应关系,并用两个星号后面的变量引用。

如果定义这样一个函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> def bar(*args, **kwargs):
...     print(f"args = {args}")
...     print(f"kwargs = {kwargs}")
...
>>> bar(1, 2, 3, lang="python", author="laoqi")
args = (1, 2, 3)
kwargs = {'lang': 'python', 'author': 'laoqi'}

是不是囊括一切,很“万能”了。的确能够收集任何多个位置参数和关键词参数,但是不要认为这种方式推广到任何函数中都是好事。在很多函数中,我们能够明确知道参数的个数,就不需要这种“万能”方式,毕竟在函数体内如果要用到那些对象,还必须给元组或字典“解包”。

用一个星号或者两个星号收集参数,并不一定非要提供数量大于等于

1

的实参,也可以这样做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> bar(1, 2, 3)
args = (1, 2, 3)
kwargs = {}
>>> bar()
args = ()
kwargs = {}

不会报错,只是元组或字典为空罢了。

特别注意,下面的定义方式是错误的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> def bar(**kwargs, *args):
  File "<stdin>", line 1
    def bar(**kwargs, *args):
                      ^
SyntaxError: invalid syntax

7.1.3节提到过,位置参数必须在关键词参数之前,收集参数的写法也遵循这个原则。

7.2.2 解包

所谓解包,就是获得容器类对象中的成员。星号用于对容器的解包,其方法与7.2.1的收集参数类似。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> lst = [1, 2, 3, 4, 5]
>>> *a = lst               # (2)
  File "<stdin>", line 1
SyntaxError: starred assignment target must be in a list or tuple

注释(2)的写法不正确,请注意如何修改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> *a, = lst
>>> a
[1, 2, 3, 4, 5]

虽然这么写没有报错,但根本没有实现“解包”的目的。“天生我材必有用”,它可以用在这里:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> range(10)
range(0, 10)
>>> *r, = range(10)    #(3)
>>> r
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Python 内置函数 range() 返回的是可迭代的 range 对象,第6章6.3.1节曾用 list() 函数对其进行类型转换,才能读取到其成员,这里使用注释(3)即可得到 range 对象中的成员,实现“解包”功能。

根据列表的知识,如果要截取列表中的部分项,可以通过切片操作实现,此外,还可以用下面的方式完成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> a, *b, c = lst    # (4)
>>> a
1
>>> b
[2, 3, 4]
>>> c
5

注释(4)分别用变量 ac 引用了列表中第一项和最后一项,其余成员用 b 引用。

以此前写过的加法函数为例,会看到更精彩的解包操作:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> def add(x, y):
...     return x + y
...
>>> num = [2, 3]
>>> add(*num)     # (5)
5

函数 add() 用以实现两个对象的 + 运算,列表 num 中有两个整数,如果让它们两个相加,一种解决方案是通过索引分别得到这两个数,即 add(num[0], num[1]) 。现在用星号对这个容器解包,以注释(5)中的 *num 作为函数的参数,即可将其中的两个成员从序列中提取出来,作为函数 add() 的位置参数。

还可以 add() 中的形参名称为键,创建一个字典,然后以下述代码中注释(6)的形式调用函数,从字典中解包出键值对,实现以关键词参数形式向函数传值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> d = {"x": 2, "y": 3}
>>> add(**d)    # (6)
5

在第4章4.2.7节学过字符串的一个方法 format() ,用于字符串格式化输出,其参数也可以用两个星号对字典解包(如下述代码注释(7)所示)。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> painter = {'name': 'Dynami', 'city': "Soochow"}
>>> "{name} is from {city}".format(**painter)    # (7)
'Dynami is from Soochow'

此外,在容器的合并上,也能使用星号,让代码显得更简洁紧凑。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> lst1 = [1, 2, 3]
>>> lst2 = [4, 5, 6]
>>> new_lst = [*lst1, *lst2]    # (8)
>>> new_lst
[1, 2, 3, 4, 5, 6]

将列表 lst1list2 合并为同一个列表,可以使用 + 将两个列表链接起来,也可以使用注释(8)实现同样的操作。其他类型的容器,也类似:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> t1 = (1, 2, 3)
>>> t2 = (3, 4, 5)
>>> (*t1, * t2)
(1, 2, 3, 3, 4, 5)
>>> s1 = {1,2,3}
>>> s2 = {3,4,5}
>>> {*s1, *s2}
{1, 2, 3, 4, 5}

对于字典,当然要用两个星号:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>>> d1 = {'author': 'laoqi', 'lang':'python'}
>>> d2 = {'price': 66, 'age': 30}
>>> d = {**d1, **d2}
>>> d
{'author': 'laoqi', 'lang': 'python', 'price': 66, 'age': 30}

自学建议 适时总结,是一种非常重要的自学方法。以本节所学习的“星号”为例,从乘法到解包操作,本书中都零零散散介绍过了。读者在学习过程中,如果觉得内容有点凌乱,很希望有人能将所有的东西总结到一张纸上的话。真正的自学者,就不要期望别人做这件事,要自己动手,才能构建起完整的、清晰的、能更新的知识结构。 ”

点击【阅读原文】,查看书稿的有关介绍和更多内容。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
彻底弄懂Python中单星号和双星号的使用
在Python中有两个重要的符号:*和**,本文通过实际案例来详细讲解它们的用法。
皮大大
2024/07/18
3200
开源图书《Python完全自学教程》6.1.2-3import和del语句
用 Python 关键词(保留字) import 发起的语句,即为 import 语句。对此我们不陌生,比如:
老齐
2022/05/17
9180
开源图书《Python完全自学教程》第5章
将字符串、列表和元组视为序列,是因为组成它们的成员具有顺序。这是对 Python 内置对象归类的一种方式。在有的资料中,还提出了“基础对象类型”的类别,包括整数类型、浮点数类型、字符串类型和布尔类型。所以,根据对象的不同特点,可以有不同的聚类结果。本章中的“容器”,也是一种归类方式,一般认为包括列表、元组和字典、集合(含可变集合和不变集合),前两种对象已经在第4章学习过,这里将开始学习后两种。诚然,读者也可以创造其他的归类方式。
老齐
2022/05/17
6670
开源图书《Python完全自学教程》第5章
开源图书《Python完全自学教程》第5.1.3节
在程序中,如果遇到这个错误,程序就会中止运行,能不能对这种情况进行处理?Python 的字典方法中给出两种处理方案。
老齐
2022/05/17
7300
开源图书《Python完全自学教程》第5.1.3节
盘一盘 Python 系列特别篇 - All 和 Any
逻辑很简单,对于一个数 n,只有从 2 到 n 做个循环,来检查 n 是不是被每个数能整除,如果是,那么 n 不是质数;如果不是,n 是质数。简单明了,代码如下。
用户5753894
2020/04/24
4970
盘一盘 Python 系列特别篇 - All 和 Any
Python与人工智能——24、for循环基础练习题——判断质数/素数
Python作为当前最为流行的一种语言与身份程序员的大家们几乎是时时刻刻分不开的,无论是做任何方面的工作基本上不会缺少Python的出现,就好似现阶段各平台的低代码Agent开发都支持的是Python语言,对其它的语言友好度都不是很高,那么,我们就非常的有必要将Python深入的了解一下,本系列文章的目的就是为了让大家对于Python有个更加直观的了解,并且要使用Python做很多的小应用,只有真正的实操了才能更好的掌握它。
红目香薰
2024/09/27
1790
Python与人工智能——24、for循环基础练习题——判断质数/素数
[重学Python]Day3 函数和模块的使用
为了解决重复代码的问题,我们可以封装重复的代码到“函数”的功能模块中,在需用使用该功能的地方,我们只需要“调用”这个“函数”就可以了。
李鹏华
2024/04/20
1350
让你的Python代码更加Pythonic
刚开始学习Python的时候,我们就了解了python的编码风格要求,通过python终端方式输入import this可以看到它的具体描述。
吾非同
2022/02/22
7540
让你的Python代码更加Pythonic
如何运用Python中函数的魔法参数,*args 和 **kwargs 真的很重要!!!
在Python中,*args 和 **kwargs 是用于函数定义中的特殊语法,它们允许函数接收可变数量的参数。*args 用于接收任意数量的位置参数(非关键字参数),而 **kwargs 用于接收任意数量的关键字参数。
小白的大数据之旅
2024/11/25
3590
如何运用Python中函数的魔法参数,*args 和 **kwargs 真的很重要!!!
Python3 * 和 ** 运算符
你可以将不定数量的参数传递给一个函数。不定的意思是:预先并不知道, 函数使用者会传递多少个参数给你, 所以在这个场景下使用这两个关键字。其实并不是必须写成 *args 和 **kwargs。  *(星号) 才是必须的. 你也可以写成 *ar  和 **k 。而写成 *args 和**kwargs 只是一个通俗的命名约定。
py3study
2020/01/13
5190
Python有趣的解包用法
python中的解包可以这样理解:一个list是一个整体,想把list中每个元素当成一个个个体剥离出来,这个过程就是解包,我们来看下面这些例子(分为10个部分)。
Python中文社区
2018/07/26
8370
开源图书《Python完全自学教程》6.5while循环语句
for 循环必须以可迭代对象作为被循环的对象,while 循环则不同,它是依据一定的条件进行循环,即只要满足某条件,循环体中的语句“总跑着”。
老齐
2022/07/06
8560
开源图书《Python完全自学教程》6.5while循环语句
Python初学者应该了解的星号(*)
特别是星号(*),在Python中是一个用途广泛的操作符,而不仅仅用于两个数字相乘的运算之中。在本文中,我们将讨论星号的多种用途。
老齐
2020/05/15
1.1K0
Python初学者应该了解的星号(*)
开源图书《Python完全自学教程》7.1.2 return语句
了解了定义函数的基本格式之后,对其中的某些细节进行深入分析、透彻了解,才能定义出具有强大功能的函数。
老齐
2022/07/06
9220
开源图书《Python完全自学教程》7.1.2 return语句
开源图书《Python完全自学教程》5.3引用和拷贝
在第2章2.3节学习变量的时候曾强调过 Python 中的变量与对象之间是引用关系。以列表为例:
老齐
2022/05/17
2690
开源图书《Python完全自学教程》5.3引用和拷贝
Python装饰器和闭包
闭包 python是一种面向对象的编程语言,在Python中一切皆是对象。函数也是对象。变量拥有的属性,函数同样拥有。因此在函数内部创建一个函数的行为是完全合法的。这种函数称为嵌套函数或者内嵌函数。闭包称为词法闭包或者函数闭包,是引用了自由变量的函数 ,两个特点 定义在另一个函数里面,嵌套作用 内部函数对外部函数作用域里面变量的引用 函数内部的变量或者函数,只有函数执行期间有生命周期 def func(): # 外部函数 a = 1 # 外部函数作用域里的变量 print("t
皮大大
2021/03/02
3900
day12- 函数
我们学习编程的时候,一学到函数就感觉很难,其实函数很简单,听我给你细细道来,在我们之前的学习中,我们最常用的一个操作,打印输出print(),其实这就是我们最先接触的函数,只不过这是由Python源码中编写好的函数,那我们来看下print()函数到底是怎么写的?
似小陈吖
2024/04/03
1150
day12- 函数
[重学Python]Day3 函数和模块的使用
项目链接:https://github.com/jackfrued/Python-100-Days
李鹏华
2024/04/15
1540
开源图书《Python完全自学教程》7.1.3参数
图7-1-1所示的函数基本格式中,圆括号里面的参数是可选项。如果为空,即没有参数,如前面使用过的函数 laoqi() 那样。如果不为空,如7.1.2节中定义的 fibo_loop() 函数那样,在调用它的时候就要“向函数传对象”——注意带有引号的说法。在 Python 中,“向函数传对象”或者“向函数传值”、“向函数传参数”,这些说法的含义都是一样的,也都是简化了的俗语——不严格,但形象直接。
老齐
2022/07/06
3340
开源图书《Python完全自学教程》7.1.3参数
开源图书《Python完全自学教程》6.3.1循环语句初步应用
for 循环语句普遍存在多种常见的高级编程语言,在 Python 中地位尤为重要,何以见得?学然后即知。
老齐
2022/05/17
5710
开源图书《Python完全自学教程》6.3.1循环语句初步应用
推荐阅读
相关推荐
彻底弄懂Python中单星号和双星号的使用
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文