前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小说python中的*和**

小说python中的*和**

作者头像
用户2196567
修改2018-12-25 11:30:26
7350
修改2018-12-25 11:30:26
举报
文章被收录于专栏:chafezhouchafezhou

python中应该经常看到*和**,这两个运算符有时可能有点神秘,特别是它们作为前缀运算符时,有时知道就是这么写,但要说清楚为什么这么写,就有些傻傻说不上了。这不是咱们的错,是python把*和**用坏了,为它们赋予了太多用途,本文就小说下,*和**都能做些什么。

本文不讨论*和**作为中缀运算符(算术运算符),也不重点涉及可变参数和关键字参数

一、传递参数

代码语言:javascript
复制
list_nums = [2, 1, 3, 4, 7]

如果要打印list_nums中的每一个元素,这种应该最直接

代码语言:javascript
复制
for elem in list_nums or []:
    print(elem)

但如果这样写呢

代码语言:javascript
复制
print(*list_nums)

这就是*在调用函数时,可以将可迭代的参数中所有元素作为独立参数进行函数调用,不用关心实际有多少个参数

仔细体会下这个列子

代码语言:javascript
复制
def transpose_list(list_of_lists):
    return [
        list(row)
        for row in zip(*list_of_lists)
    ]


>> transpose_list([[1, 4, 7], [2, 5, 8], [3, 6, 9]])
>> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

**运算符也有类似的用法

代码语言:javascript
复制
>>> date_info = {'year': "2020", 'month': "01", 'day': "01"}
>>> filename = "{year}-{month}-{day}.txt".format(**date_info)
>>> filename
'2020-01-01.txt'

二、指定关键字参数

定义如下函数:

代码语言:javascript
复制
def get_multiple(*keys, dictionary, default=None):
    return [
        dictionary.get(key, default)
        for key in keys
    ]

这样调用函数是不行的

代码语言:javascript
复制
>>> 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'

必须指定关键字参数

代码语言:javascript
复制
>>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'}
>>> get_multiple('lemon', 'tomato', 'squash', dictionary=fruits, default='unknown')
['yellow', 'red', 'unknown']

再看下面这个函数

代码语言:javascript
复制
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

这样调用也是不行的

代码语言:javascript
复制
>>> 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关键字参数不能少)

代码语言:javascript
复制
>>> list(with_previous([2, 1, 3], fillvalue=0))
[(0, 2), (2, 1), (1, 3)]

这样就可以强行指定函数中某个位置必须是指定的参数

python内置函数sorted就是使用的此方法

三、元组解包

代码语言:javascript
复制
>>> 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']

这样就可以完成类似切片的操作

代码语言:javascript
复制
>>> numbers = [1, 2, 3, 4, 5, 6]


>>> beginning, last = numbers[:-1], numbers[-1]
>>> *beginning, last = numbers

>>> head, middle, tail = numbers[0], numbers[1:-1], numbers[-1]
>>> head, *middle, tail = numbers

获取命令行参数也可以这样做了

代码语言:javascript
复制
program_name, *arguments = sys.argv

四、迭代转存

代码语言:javascript
复制
>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato']
>>> (*fruits[1:], fruits[0])
('pear', 'watermelon', 'tomato', 'lemon')

通常会这么写

代码语言:javascript
复制
tuple(fruits[1:] + fruits[0:1])

但+只能操作部分数据类型而且必须是相同类型的对象,*没有任何限制,如下,转存list和一个generatorset

代码语言:javascript
复制
fruits = ['lemon', 'pear', 'watermelon', 'tomato']

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

** 也有类似操作

合并两个dict

代码语言:javascript
复制
>>> 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'}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-12-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 chafezhou 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档