python中应该经常看到*和**,这两个运算符有时可能有点神秘,特别是它们作为前缀运算符时,有时知道就是这么写,但要说清楚为什么这么写,就有些傻傻说不上了。这不是咱们的错,是python把*和**用坏了,为它们赋予了太多用途,本文就小说下,*和**都能做些什么。
本文不讨论*和**作为中缀运算符(算术运算符),也不重点涉及可变参数和关键字参数
一、传递参数list_nums = [2, 1, 3, 4, 7]
如果要打印list_nums中的每一个元素,这种应该最直接for elem in list_nums or []:
print(elem)
但如果这样写呢print(*list_nums)
这就是*在调用函数时,可以将可迭代的参数中所有元素作为独立参数进行函数调用,不用关心实际有多少个参数
仔细体会下这个列子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]]
**运算符也有类似的用法>>> date_info = {‘year’: “2020”, ‘month’: “01”, ‘day’: “01”}
>>> filename = “{year}-{month}-{day}.txt”.format(**date_info)
>>> filename
‘2020-01-01.txt’
二、指定关键字参数
定义如下函数: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’, fruits, ‘unknown’)
Traceback (most recent call last):
File “”, line 1, in
TypeError: get_multiple() missing 1 required keyword-only argument: ‘dictionary’
必须指定关键字参数>>> fruits = {‘lemon’: ‘yellow’, ‘orange’: ‘orange’, ‘tomato’: ‘red’}
>>> get_multiple(‘lemon’, ‘tomato’, ‘squash’, dictionary=fruits, default=’unknown’)
[‘yellow’, ‘red’, ‘unknown’]
再看下面这个函数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
这样调用也是不行的>>> list(with_previous([2, 1, 3], 0))
Traceback (most recent call last):
File “”, line 1, in
TypeError: with_previous() takes 1 positional argument but 2 were given
必须这样调用(fillvalue关键字参数不能少)>>> list(with_previous([2, 1, 3], fillvalue=0))
[(0, 2), (2, 1), (1, 3)]
这样就可以强行指定函数中某个位置必须是指定的参数
python内置函数sorted就是使用的此方法
三、元组解包>>> 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’]
这样就可以完成类似切片的操作>>> 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
获取命令行参数也可以这样做了program_name, *arguments = sys.argv
四、迭代转存>>> fruits = [‘lemon’, ‘pear’, ‘watermelon’, ‘tomato’]
>>> (*fruits[1:], fruits[0])
(‘pear’, ‘watermelon’, ‘tomato’, ‘lemon’)
通常会这么写tuple(fruits[1:] + fruits[0:1])
但+只能操作部分数据类型而且必须是相同类型的对象,*没有任何限制,如下,转存list和一个generator为setfruits = [‘lemon’, ‘pear’, ‘watermelon’, ‘tomato’]
>>> uppercase_fruits = (f.upper() for f in fruits)
>>> {*fruits, *uppercase_fruits}
{‘lemon’, ‘watermelon’, ‘TOMATO’, ‘LEMON’, ‘PEAR’, ‘WATERMELON’, ‘tomato’, ‘pear’}
** 也有类似操作
合并两个dict>>> date_info = {‘year’: “2020”, ‘month’: “01”, ‘day’: “01”}
>>> track_info = {‘artist’: “Beethoven”, ‘title’: ‘Symphony No 5’}
>>> all_info = 便宜香港vps {**date_info, **track_info}
>>> all_info
{‘year’: ‘2020’, ‘month’: ’01’, ‘day’: ’01’, ‘artist’: ‘Beethoven’, ‘title’: ‘Symphony No 5’}
49899450