python中前缀运算符 *和 **的用法示例详解


Posted in Python onMay 28, 2020

这篇主要探讨 ** 和 * 前缀运算符,**在变量之前使用的*and **运算符.

一个星(*):表示接收的参数作为元组来处理

两个星(**):表示接收的参数作为字典来处理

简单示例:

>>> numbers = [2, 1, 3, 4, 7]
>>> more_numbers = [*numbers, 11, 18]
>>> print(*more_numbers, sep=', ')
2, 1, 3, 4, 7, 11, 18

用途:

  • 使用 * 和 ** 将参数传递给函数
  • 使用**和**捕获传递给函数的参数
  • 使用*只接受关键字参数
  • 使用*元组拆包过程中捕获项目
  • 使用*解包iterables到一个列表/元组
  • 使用**要解压缩词典到其他字典

例子解释:

1.调用函数时,*可以使用运算符将​​可迭代对象解压缩为函数调用中的参数:

>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato']
>>> print(fruits[0], fruits[1], fruits[2], fruits[3])
lemon pear watermelon tomato
>>> print(*fruits)
lemon pear watermelon tomato

该print(*fruits)行将fruits列表中的所有项目print作为单独的参数传递到函数调用中,而我们甚至不需要知道列表中有多少个参数。

2.** 运算符允许我们采取键值对的字典,并把它解压到函数调用中的关键字参数。

>>> date_info = {'year': "2020", 'month': "01", 'day': "01"}
>>> filename = "{year}-{month}-{day}.txt".format(**date_info)
>>> filename
'2020-01-01.txt'

** 将关键字参数解包到函数调用中并不是很常见。我最常看到的地方是练习继承时:super()通常要同时包含*和**。
双方*并 **可以在函数调用中多次使用,像Python 3.5的。

>> fruits = ['lemon', 'pear', 'watermelon', 'tomato']
>>> numbers = [2, 1, 3, 4, 7]
>>> print(*numbers, *fruits)
2 1 3 4 7 lemon pear watermelon tomato
**多次使用类似:

>>> date_info = {'year': "2020", 'month': "01", 'day': "01"}
>>> track_info = {'artist': "Beethoven", 'title': 'Symphony No 5'}
>>> filename = "{year}-{month}-{day}-{artist}-{title}.txt".format(
...   **date_info,
...   **track_info,
... )
>>> filename
'2020-01-01-Beethoven-Symphony No 5.txt'

3.定义函数时,*可以使用运算符捕获为函数提供的无限数量的位置参数。这些参数被捕获到一个元组中。

from random import randint

def roll(*dice):
  return sum(randint(1, die) for die in dice

4.我们可以用**定义一个函数时,捕捉给予功能到字典中的任何关键字参数:

def tag(tag_name, **attributes):
  attribute_list = [
    f'{name}="{value}"'
    for name, value in attributes.items()
  ]
  return f"<{tag_name} {' '.join(attribute_list)}>"

5.带有仅关键字参数的位置参数,要接受仅关键字的参数,可以*在定义函数时在使用后放置命名参数

def get_multiple(*keys, dictionary, default=None):
  return [
    dictionary.get(key, default)
    for key in keys
  ]
上面的函数可以这样使用:

>>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'}
>>> get_multiple('lemon', 'tomato', 'squash', dictionary=fruits, default='unknown')
['yellow', 'red', 'unknown']

参数dictionaryand default在其后*keys,这意味着只能将它们指定为关键字参数。如果我们尝试在位置上指定它们,则会收到错误消息:

>>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'}
>>> get_multiple('lemon', 'tomato', 'squash', fruits, 'unknown')
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: get_multiple() missing 1 required keyword-only argument: 'dictionary'

6.不带位置参数的仅关键字参数
仅关键字参数的功能很酷,但是如果您需要仅关键字参数而不捕获无限的位置参数怎么办?

def with_previous(iterable, *, fillvalue=None):
  """Yield each iterable item along with the item before it."""
  previous = fillvalue
  for item in iterable:
    yield previous, item
    previous = item
  ```

该函数接受一个iterable参数,该参数可以在位置上指定(作为第一个参数),也可以通过其名称和作为fillvalue仅关键字参数的参数来指定。这意味着我们可以这样调用with_previous:

>>> list(with_previous([2, 1, 3], fillvalue=0))
[(0, 2), (2, 1), (1, 3)]
但不是这样的:
>>> list(with_previous([2, 1, 3], 0))
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: with_previous() takes 1 positional argument but 2 were given
此函数接受两个参数,并且其中一个fillvalue 必须指定为关键字arguments。

7.元组拆包中的星号

Python 3还添加了一种新的使用运算符的方式,该方式仅与上面的-when-defining-a-function和*-when-when-calling-afunction功能有关。

>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato']
>>> first, second, *remaining = fruits
>>> remaining
['watermelon', 'tomato']
>>> first, *remaining = fruits
>>> remaining
['pear', 'watermelon', 'tomato']
>>> first, *middle, last = fruits
>>> middle
['pear', 'watermelon']

8.列表文字中的星号
Python 3.5 通过PEP 448引入了大量的新功能。最大的新功能之一是能够将可迭代对象转储到新列表中。

假设您有一个函数,该函数可以接收任何序列,并返回一个列表,其中该序列与该序列的反序连接在一起:

def palindromify(sequence):
  return list(sequence) + list(reversed(sequence))

该函数需要将事物转换为列表几次,以连接列表并返回结果。在Python 3.5中,我们可以改为输入:

def palindromify(sequence):
   return [*sequence, *reversed(sequence)]

 此代码删除了一些不必要的列表调用,因此我们的代码更加高效和可读。

这是另一个例子:

def rotate_first_item(sequence):
   return [*sequence[1:], sequence[0]]

该函数返回一个新列表,其中给定列表(或其他序列)中的第一项移动到新列表的末尾。

* 运算符的这种使用是将不同类型的可迭代对象连接在一起的好方法。的*操作者适用于任何可迭代,而使用+操作者仅适用于具有所有相同类型的特定序列。

这不仅限于创建列表。我们还可以将可迭代项转储到新的元组或集合中:

>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato']
>>> (*fruits[1:], fruits[0])
('pear', 'watermelon', 'tomato', 'lemon')
>>> uppercase_fruits = (f.upper() for f in fruits)
>>> {*fruits, *uppercase_fruits}
{'lemon', 'watermelon', 'TOMATO', 'LEMON', 'PEAR', 'WATERMELON', 'tomato', 'pear'}

请注意,上面的最后一行获取一个列表和一个生成器,并将它们转储到新集中。在使用之前*,以前没有一种简单的方法可以在一行代码中做到这一点。以前有一种方法可以做到,但要记住或发现它并不容易:

>>> set().union(fruits, uppercase_fruits)
{'lemon', 'watermelon', 'TOMATO', 'LEMON', 'PEAR', 'WATERMELON', 'tomato', 'pear'}

9.字典文字中的双星号
PEP 448还**允许该运算符用于将键/值对从一个字典转储到新字典中,从而扩展了功能:

>>> date_info = {'year': "2020", 'month': "01", 'day': "01"}
>>> track_info = {'artist': "Beethoven", 'title': 'Symphony No 5'}
>>> all_info = {**date_info, **track_info}
>>> all_info
{'year': '2020', 'month': '01', 'day': '01', 'artist': 'Beethoven', 'title': 'Symphony No 5'}

例如,我们可以在添加新值的同时复制字典:

>>> date_info = {'year': '2020', 'month': '01', 'day': '7'}
>>> event_info = {**date_info, 'group': "Python Meetup"}
>>> event_info
{'year': '2020', 'month': '01', 'day': '7', 'group': 'Python Meetup'}

或在覆盖特定值的同时复制/合并字典:

>>> event_info = {'year': '2020', 'month': '01', 'day': '7', 'group': 'Python Meetup'}
>>> new_info = {**event_info, 'day': "14"}
>>> new_info
{'year': '2020', 'month': '01', 'day': '14', 'group': 'Python Meetup'}

ref: https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/

总结

到此这篇关于python中前缀运算符 *和 **的用法示例详解的文章就介绍到这了,更多相关python中 *和 **的用法内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
详解JavaScript编程中的window与window.screen对象
Oct 26 Python
django+js+ajax实现刷新页面的方法
May 22 Python
Python 使用类写装饰器的小技巧
Sep 30 Python
python 实现查找文件并输出满足某一条件的数据项方法
Jun 12 Python
简单了解python的break、continue、pass
Jul 08 Python
python elasticsearch从创建索引到写入数据的全过程
Aug 04 Python
numpy求平均值的维度设定的例子
Aug 24 Python
python实现的接收邮件功能示例【基于网易POP3服务器】
Sep 11 Python
python爬虫-模拟微博登录功能
Sep 12 Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
Dec 11 Python
python 实现将Numpy数组保存为图像
Jan 09 Python
基于tensorflow权重文件的解读
May 26 Python
PHP基于phpqrcode类库生成二维码过程解析
May 28 #Python
Python函数参数分类原理详解
May 28 #Python
pygame用blit()实现动画效果的示例代码
May 28 #Python
PyCharm中如何直接使用Anaconda已安装的库
May 28 #Python
Python内置异常类型全面汇总
May 28 #Python
python不到50行代码完成了多张excel合并的实现示例
May 28 #Python
python使用openpyxl操作excel的方法步骤
May 28 #Python
You might like
使用正则去除php代码中的注释方法
2016/11/03 PHP
浅谈socket同步和异步、阻塞和非阻塞、I/O模型
2016/12/15 PHP
老生常谈ThinkPHP中的行为扩展和插件(推荐)
2017/05/05 PHP
Packer 3.0 JS压缩及混淆工具 下载
2007/05/03 Javascript
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
基于jquery的兼容各种浏览器的iframe自适应高度的脚本
2010/08/13 Javascript
js当一个变量为函数时 应该注意的一点细节小结
2011/12/29 Javascript
左侧是表头的JS表格控件(自写,网上没有的)
2013/06/04 Javascript
iframe中子父类窗口调用JS的方法及注意事项
2015/08/25 Javascript
jQuery div拖拽用法实例
2016/01/14 Javascript
搞定immutable.js详细说明
2016/05/02 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
ES2015 Symbol 一种绝不重复的值
2016/12/25 Javascript
JavaScript使用delete删除数组元素用法示例【数组长度不变】
2017/01/17 Javascript
vue.js中指令Directives详解
2017/03/20 Javascript
详解Web使用webpack构建前端项目
2017/09/23 Javascript
在 Node.js 中使用 async 函数的方法
2017/11/17 Javascript
angular.js和vue.js中实现函数去抖示例(debounce)
2018/01/18 Javascript
解决vue跨域axios异步通信问题
2019/04/17 Javascript
Vue实现push数组并删除的例子
2019/11/01 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
2020/07/26 Javascript
详细解读Python中的__init__()方法
2015/05/02 Python
Python实现递归遍历文件夹并删除文件
2016/04/18 Python
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
tensorflow更改变量的值实例
2018/07/30 Python
python多进程下实现日志记录按时间分割
2019/07/22 Python
django2.2安装错误最全的解决方案(小结)
2019/09/24 Python
TensorFLow 不同大小图片的TFrecords存取实例
2020/01/20 Python
卸载tensorflow-cpu重装tensorflow-gpu操作
2020/06/23 Python
PHP面试题-$message和$$message的区别
2015/12/08 面试题
质检的岗位职责
2013/11/17 职场文书
秋季运动会活动方案
2014/02/05 职场文书
优秀实习生主要事迹
2014/05/29 职场文书
2014年学校德育工作总结
2014/12/05 职场文书
如何用JavaScript检测当前浏览器是无头浏览器
2021/04/27 Javascript
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫