1.参数解包:方法调用中的*表达式**表达式

如果语法*表达式出现在函数调用中,则该表达式必须是可迭代的。

这些可迭代集合的元素被视为附加的位置参数。

对于调用f(x1, x2, *y, x3, x4),如果y等于序列[y1,...,yM],则等效于调用f(x1, x2, y1, ..., yM, x3, x4)

如果函数调用中出现语法**表达式,则该表达式的值必须为“映射”,其内容被视为附加的关键字参数。

如果一个关键字已经存在(作为一个明确的关键字参数,或来自另一个解包),则会引发“ TypeError”异常。

关于参数顺序的说明:* 表达式可以出现在显式关键字参数之后,并在关键字参数和任何** 表达式参数之前被处理。而在一般函数的显式参数调用中,位置参数必须放在关键字参数之前。例如:

def func(a, b ,c):
print(a, b, c) func(c=3, 1, 2) # SyntaxError: positional argument follows keyword argument
func(c=3, *(1,2)) # OK. 1 2 3
func(c=3, **dict(a=1,b=2)) # OK. 1 2 3
func(c=3, *(1,), **dict(b=2)) # OK. 1 2 3

2.参数解包:方法定义中的*表达式**表达式

如果存在形式 * identifier,则将其初始化为接收任何其余位置参数的元组,默认为空元组。

如果存在形式 ** identifier,则将其初始化为一个新字典,该字典将接收任何其余的关键字参数,默认为一个新的空字典。

所以 *args其实是一个元组!

让我们来看一个例子:

def func(*args, **kwargs):
print(args)
print(kwargs)
print(locals()) func(1, a=2) # output:
# (1,)
# {'a': 2}
# {'kwargs': {'a': 2}, 'args': (1,)}

单元素元组的语法看起来有点奇怪。不过习惯就好了。

仅需使用尾部逗号就能创建单个元组(也称为单例);在所有其他情况下,逗号是可选的。没有尾部逗号的单个表达式不会创建元组,而是会产生该表达式的值。

3.在元组,列表,集合和字典中解包

>>> *range(4), 4
(0, 1, 2, 3, 4)
>>> [*range(4), 4]
[0, 1, 2, 3, 4]
>>> {*range(4), 4}
{0, 1, 2, 3, 4}
>>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}

在字典中,后一个值将始终覆盖前一个值。

  • 注意,我们也可以这样理解

    • *可迭代集合解包算子
    • **字典解包算子

4.Extended Unpacking:赋值表达式左边的*表达式

赋值表达式左侧的元组(或列表)至多可以包含一个带有单个星号的表达式(称为“星号”表达式,而列表中的其他表达式则称为“强制性”)。

强制表达式的值将根据赋值表达式右边元组(或列表)中对应的元素位置被分配。

例如,如果seq是可切分的序列,且seq具有至少2个元素,则以下所有赋值均等效:

a, *b, c = seq
[a, *b, c] = seq
a, b, c = seq[0], list(seq[1:-1]), seq[-1]
  • seq[0]保证赋值给a
  • seq[-1]保证赋值给c
  • 其余元素则赋值给b,b一定是个列表。
  • 如果 len(seq)==2,b为空列表

如果星号表达式赋值的长列表,那么会报错:

*a = range(5)  # SyntaxError: starred assignment target must be in a list or tuple

这样就可以了:

*a, = range(5)  # OK
a: [0, 1, 2, 3, 4]

该建议也适用于隐式赋值中的元组,例如在for语句中:

for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:
print(b) # output:
# [2, 3]
# [5, 6, 7]

更多的例子可以参考 stack overflow: Unpacking, Extended unpacking, and nested extended unpacking

Ref:

http://yaoyao.codes/python/2016/09/25/python-starred-expression

The Python Language Reference - 6.3.4. Calls

The Python Language Reference - 8.6. Function definitions

The Python Language Reference - 6.14. Expression lists

PEP 448 – Additional Unpacking Generalizations

PEP 3132 – Extended Iterable Unpacking

Python中的参数解包:`*`表达式和 `**`表达式的更多相关文章

  1. python之参数解包

    # 参数解包:将整个list当做参数传给函数 list = [1, 2, 4] def add_fn(a, b, c): return a + b + c sum = add_fn(*list) pr ...

  2. Python中的参数

    Python中的参数 1. python函数参数有多重形式: * test(arg1,arg2,`*args`) * test(arg1,arg2,`*args`,`**kwargs`) 2. 其中比 ...

  3. python基础之打/解包及运算符与控制流程

    python基础之打/解包及运算符与控制流程 python中的解压缩(即序列类型的打包和解包) python提供了两个设计元祖和其他序列类型的处理的便利,也就是自动打包与自动解包功能,比如: data ...

  4. python中常用的导包的方法和常用的库

    python中常用的导包的方法               导入包和包名的方法:1.import package.module 2.from package.module import  * 例一: ...

  5. Python中dict详解

    from:http://www.cnblogs.com/yangyongzhi/archive/2012/09/17/2688326.html Python中dict详解 python3.0以上,pr ...

  6. 从 python 中 axis 参数直觉解释 到 CNN 中 BatchNorm 的工作方式(Keras代码示意)

    1. python 中 axis 参数直觉解释 网络上的解释很多,有的还带图带箭头.但在高维下是画不出什么箭头的.这里阐述了 axis 参数最简洁的解释. 假设我们有矩阵a, 它的shape是(4, ...

  7. (转)python中函数参数中如果带有默认参数list的特殊情况

    在python中函数参数中如果带有默认参数list遇到问题 先看一段代码 1 2 3 4 5 6 7 8 9 def f(x,l=[]):     for i in range(x):         ...

  8. python中函数参数的引用方式

    值传递和引用传递时C++中的概念,在python中函数参数的传递是变量指向的对象的物理内存地址!!! python不允许程序员选择采用传值还是传引用.Python参数传递采用的肯定是“传对象引用”的方 ...

  9. Python 中的时间处理包datetime和arrow

    Python 中的时间处理包datetime和arrow 在获取贝壳分的时候用到了时间处理函数,想要获取上个月时间包括年.月.日等 # 方法一: today = datetime.date.today ...

随机推荐

  1. django学习 session保持登录,且登出

    学一点记一点 刚刚进来的时候突然发现,博客园的主页在缩小的时候会发生一些挤压,有点意思 今天刚看了session,感觉之前太迷茫,把问题想得过于复杂了. 我这个是建立在有登录和注册的功能上的演示. 首 ...

  2. Python爬虫连载8-JS加密(一)

    一.JS加密 1.有的反爬虫策略采用js对需要传输的数据进行加密处理. 2.经过加密,传输的就是密文 3.加密函数或者过程一定是在浏览器完成,也就是一定会把代码(js代码)暴露给使用者 4.通多阅读加 ...

  3. centos添加用户并赋予 root管理员权限

     centos添加用户并赋予 root管理员权限 用centos时,root用户一般都是超级管理员使用的,一般不轻易给别人,但是有时候同事安装软件时需要root账号,又不得不给,只能重新建一个用户,并 ...

  4. C#设置一个控件可以鼠标拖动

    C#设置一个控件可以鼠标拖动: 新建一个C#项目, 创建一个label控件, 设置label的鼠标按下和抬起事件分别为:label1_MouseDown和label1_MouseUp. 对代码进行如下 ...

  5. 关于jquery绑定事件执行两次

    经常会出现jquery绑定事件执行两次的情况,如: $("a[tag=slide]").click(function () { alert(1); $(this).parent() ...

  6. C++-POJ1015-Jury Compromise

    Java实现会MLE那我也没办法了 //辩方总分和控方总分之差简称为“辩控差” //辩方总分和控方总分之和简称为“辩控和” //现用f(j, k)表示,取j 个候选人,使其辩控差为k 的所有方案中,辩 ...

  7. 链接测试工具:Xenu

    Xenu 是一款深受业界好评,并被广泛使用的死链接检测工具.时常检测网站并排除死链接,对网站的 SEO(搜索引擎优化) 非常重要,因为大量死链接存在会降低用户和搜索引擎对网站的信任. 最大支持100线 ...

  8. 10day 字符集优化 重点

    什么是字符编码: 可以实现对非英文字符的支持 计算机操作系统是谁发明的? --美国人--英语 支持中文比较好的编码: UTF-8 比较通用 GBK 比较国际通用 出现乱码的原因: 01. 系统字符集设 ...

  9. 查看ie版本

    window10系统还好说,一般都是IE11版本,其他系统或服务器看=查看ie版本就很烦 方法一:按组合键  ALT+H 打开“帮助”,再按 A 选择“关于Internet Explorer” 方法二 ...

  10. 题解【CJOJ1070/UVA】嵌套矩形

    P1070 - [Uva]嵌套矩形 Description 有 n 个矩形,每个矩形可以用两个整数 a, b 描述,表示它的长和宽.矩形 X(a, b) 可以嵌套在矩形 Y(c, d) 中当且仅当 a ...