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 相关文章推荐
详细探究Python中的字典容器
Apr 14 Python
Python装饰器用法实例总结
Feb 07 Python
为什么入门大数据选择Python而不是Java?
Mar 07 Python
python 限制函数执行时间,自己实现timeout的实例
Jan 12 Python
python 含子图的gif生成时内存溢出的方法
Jul 07 Python
Python-接口开发入门解析
Aug 01 Python
python numpy 矩阵堆叠实例
Jan 17 Python
jupyter notebook实现显示行号
Apr 13 Python
Python实现自动打开电脑应用的示例代码
Apr 17 Python
Spy++的使用方法及下载教程
Jan 29 Python
python中使用np.delete()的实例方法
Feb 01 Python
解决python的空格和tab混淆而报错的问题
Feb 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
一些星际专用术语解释
2020/03/04 星际争霸
PHP COOKIE及时生效的方法介绍
2014/02/14 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
10个值得深思的PHP面试题
2016/11/14 PHP
php获取目录中所有文件名及判断文件与目录的简单方法
2017/03/04 PHP
基于jQuery实现图片的前进与后退功能
2013/04/24 Javascript
JQuery操作iframe父页面与子页面的元素与方法(实例讲解)
2013/11/20 Javascript
JQuery插件iScroll实现下拉刷新,滚动翻页特效
2014/06/22 Javascript
对JavaScript客户端应用编程的一些建议
2015/06/24 Javascript
详解JavaScript基于面向对象之继承
2015/12/13 Javascript
Jquery uploadify上传插件使用详解
2016/01/13 Javascript
js canvas仿支付宝芝麻信用分仪表盘
2016/11/16 Javascript
删除table表格行的实例讲解
2017/09/21 Javascript
微信小程序开发注意指南和优化实践(小结)
2019/06/21 Javascript
Vue+ElementUI table实现表格分页
2019/12/14 Javascript
详解React的回调渲染模式
2020/09/10 Javascript
微信小程序onShareTimeline()实现分享朋友圈
2021/01/07 Javascript
[02:53]DOTA2英雄昆卡基础教程
2013/11/25 DOTA
python简单获取数组元素个数的方法
2015/07/13 Python
Django中STATIC_ROOT和STATIC_URL及STATICFILES_DIRS浅析
2018/05/08 Python
Python3列表内置方法大全及示例代码小结
2019/05/10 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
2019/07/18 Python
python 根据字典的键值进行排序的方法
2019/07/24 Python
Python线程条件变量Condition原理解析
2020/01/20 Python
python next()和iter()函数原理解析
2020/02/07 Python
关于Python turtle库使用时坐标的确定方法
2020/03/19 Python
Pycharm 2020.1 版配置优化的详细教程
2020/08/07 Python
html5唤醒APP小记
2019/03/27 HTML / CSS
奥地利度假券的专家:we-are.travel
2019/04/10 全球购物
酒店前厅员工辞职信
2014/01/08 职场文书
经贸韩语专业大学生职业规划
2014/02/14 职场文书
标准化管理实施方案
2014/02/25 职场文书
学生手册评语
2014/05/05 职场文书
政风行风建设责任书
2014/07/23 职场文书
医院财务人员岗位职责
2015/04/14 职场文书
2015年宣传部个人工作总结
2015/05/14 职场文书