51Testing软件测试论坛

标题: Python中星号的五种用法分享 [打印本页]

作者: lsekfe    时间: 2023-2-21 10:50
标题: Python中星号的五种用法分享
1. 引言
  星号* 往往被称为乘法运算符,是所有程序中最为常用的运算符号之一,在Python 中,星号还有很多隐藏的强大功能。
  本文将用最容易理解的例子来解释星号*的 五个使用场景,从初级用法到高阶用法。
  闲话少说,我们直接开始吧!
  2. 乘法和幂运算符
  最简单的用法是利用星号作为基本的运算符:
  ● 单个 * 用于乘法运算
  ● 两个 ** 表示幂运算
  相关样例用例代码如下:
  >>> 2*3
  >>> 6
  >>> 2**3
  >>> 8


  3. 函数接收数量不固定的入参
  一般来说,函数往往接收固定数量的参数;但是如果我们需要更大的灵活性,比如当不确定将传递多少个参数时,此时将是星号* 发挥作用的时候。
  def print_genius(*names):
      print(type(names))
      for n in names:
          print(n)
  print_genius('Elon Mask', 'Du Fu ', 'Li Bai')
  # <class 'tuple'>
  # Elon Mask
  # Du Fu
  # Li Bai
  def top_genius(**names):
      print(type(names))
      for k, v in names.items():
          print(k, v)
  top_genius(Top1="Elon Mask", Top2="Du Fu", Top3="Li Bai")
  # <class 'dict'>
  # Top1 Elon Mask
  # Top2 Du Fu
  # Top3 Li Bai


  如上例所示,在定义函数时,我们可以定义一个以一个或两个星号为前缀的参数,以捕获不限制数量的参数输入。总结如下:
  ● 以 一个 * 为前缀的参数可以将任意数量的参数以元组形式传入
  ● 以两个 ** 为前缀的参数可以将任意数量的参数以字典形式传入
  按照惯例,当我们定义的函数接收不定数量的参数时,我们一般采用以下函数定义形式:
  def func(*args, **kwargs):
      pass


  4. 限制函数入参仅以关键字形式输入
  星号* 的一个非常酷的用法是使函数只能接收关键字参数。
  很难理解,我们举例来说明:
  def genius(*, first_name, last_name):
      print(first_name, last_name)
  # genius('Li','Bai')
  # TypeError: genius() takes 0 positional arguments but 2 were given
  genius(first_name='Li', last_name='Bai')
  # Li Bai


  上述代码采用了星号* 限制了星号之后的参数必须采用关键字形式来调用上述函数。
  实际上,如果我们只是想将一些参数限制为仅以关键字形式输入同时另一部分参数依旧按照位置形式输入,此时我们可以将位置参数放置在星号之前。
  样例代码如下:
  def genius(age, *, first_name, last_name):
      print(first_name, last_name, 'is', age)
  genius(28, first_name='Li', last_name='Bai')
  # Li Bai is 28


  5. 可迭代对象解包操作
  我们可以使用星号* 来解包可迭代对象,这将使我们的程序更加清晰且优雅。
  例如,如果我们要将不同的可迭代对象(例如一个列表,一个元组和一个集合)组合成一个新列表,哪种方法最好?
  显然,我们可以使用 for 循环来迭代所有元素并将它们逐一添加到新列表中,样例代码如下:
  A = [1, 2, 3]
  B = (4, 5, 6)
  C = {7, 8, 9}
  L = []
  for a in A:
      L.append(a)
  for b in B:
      L.append(b)
  for c in C:
      L.append(c)
  print(L)
  # [1, 2, 3, 4, 5, 6, 8, 9, 7]


  上述实现方式虽然可以完成我们的目的,但是代码看起来太冗长了,而且不是很Pythonic 。
  推荐的改进方式是使用列表生成式,如下所示:
  A = [1, 2, 3]
  B = (4, 5, 6)
  C = {7, 8, 9}
  L = [a for a in A] + [b for b in B] + [c for c in C]
  print(L)
  # [1, 2, 3, 4, 5, 6, 8, 9, 7]


  上述代码中,我们将三个 for 循环减少为一行列表生成式。它已经是Pythonic了,但不一定是最简单的!
  是时候看看星号的强大之处啦。
  A = [1, 2, 3]
  B = (4, 5, 6)
  C = {7, 8, 9}
  L = [*A, *B, *C]
  print(L)
  # [1, 2, 3, 4, 5, 6, 8, 9, 7]


  如上所述,我们可以使用星号作为可迭代项的前缀来解包它们的元素。
  顺便说一句,如果我们利用一个*作为dict 的前缀,它的key 将被解包;如果我们使用双星号** 作为前缀,其value 将被解包;此时我们必须显示使用key 来接收解包后的value 。
  样例如下:
  D = {'first': 1, 'second': 2, 'third': 3}
  print(*D)
  # first second third
  # print(**D)
  # TypeError: 'first' is an invalid keyword argument for print()
  print('{first},{second},{third}'.format(**D))
  # 1,2,3


  6. 扩展可迭代对象解包
  解包的语法可以让我们的代码更加简洁,样例如下:
  L = [1, 2, 3, 4, 5, 6, 7, 8]
  a, *b = L
  print(a)
  # 1
  print(b)
  # [2, 3, 4, 5, 6, 7, 8]


  7. 结论
  星号* 是程序中最常用的运算符之一。除了用作乘法运算符之外,它在Python中还有一些优雅而强大的用法,这将帮助我们的代码变得更加Pythonic 。
  本文重点讲解了星号的五种用法,并给出了相应的代码示例,您学废了嘛?


作者: jingzizx    时间: 2023-3-7 14:06





欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2