在Python中扩展和传递列表、图元和字典作为函数参数

商业

在 Python 中,列表 (数组)、图元和字典可以被展开 (解包),它们各自的元素可以作为函数参数一起传递。

当调用一个函数时,对列表和图元用*指定参数,对字典用**指定参数。注意星号*的数量。

这里介绍一下以下细节。

  • 用*(一个星号)扩展(解包)一个列表或元组
    • 对于有默认参数的函数
    • 对于具有可变长度参数的函数
  • 用**(两个星号)扩展(解压)字典
    • 对于有默认参数的函数
    • 对于具有可变长度参数的函数

关于Python函数的基本用法,默认参数,以及定义函数时用*,**的可变长度参数,请看下面的文章。

用*(一个星号)扩展(解包)一个列表或元组

当一个列表或元组被指定为一个带*的参数时,它被展开,每个元素被作为一个单独的参数传递。

def func(arg1, arg2, arg3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

l = ['one', 'two', 'three']

func(*l)
# arg1 = one
# arg2 = two
# arg3 = three

func(*['one', 'two', 'three'])
# arg1 = one
# arg2 = two
# arg3 = three

t = ('one', 'two', 'three')

func(*t)
# arg1 = one
# arg2 = two
# arg3 = three

func(*('one', 'two', 'three'))
# arg1 = one
# arg2 = two
# arg3 = three

下面的解释是针对列表的,但同样适用于元组。

如果元素的数量与参数的数量不一致,就会发生TypeError错误。

# func(*['one', 'two'])
# TypeError: func() missing 1 required positional argument: 'arg3'

# func(*['one', 'two', 'three', 'four'])
# TypeError: func() takes 3 positional arguments but 4 were given

对于有默认参数的函数

如果设置了默认参数,如果元素的数量不足,就使用默认参数。如果元素的数量太多,就会发生TypeError错误。

def func_default(arg1=1, arg2=2, arg3=3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

func_default(*['one', 'two'])
# arg1 = one
# arg2 = two
# arg3 = 3

func_default(*['one'])
# arg1 = one
# arg2 = 2
# arg3 = 3

# func_default(*['one', 'two', 'three', 'four'])
# TypeError: func_default() takes from 0 to 3 positional arguments but 4 were given

对于具有可变长度参数的函数

如果设置了一个可变长度的参数,那么位置参数的元素之后的所有元素都会传递给可变长度的参数。

def func_args(arg1, *args):
    print('arg1 =', arg1)
    print('args =', args)

func_args(*['one', 'two'])
# arg1 = one
# args = ('two',)

func_args(*['one', 'two', 'three'])
# arg1 = one
# args = ('two', 'three')

func_args(*['one', 'two', 'three', 'four'])
# arg1 = one
# args = ('two', 'three', 'four')

用**(两个星号)扩展(解压)字典

当字典dict被指定为带**的参数时,元素key被扩展为参数名,value被扩展为参数值,并且每个元素都作为一个单独的参数传递。

def func(arg1, arg2, arg3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

d = {'arg1': 'one', 'arg2': 'two', 'arg3': 'three'}

func(**d)
# arg1 = one
# arg2 = two
# arg3 = three

func(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three'})
# arg1 = one
# arg2 = two
# arg3 = three

如果没有与参数名称相匹配的键,或者有一个不匹配的键,将产生一个TypeError错误。

# func(**{'arg1': 'one', 'arg2': 'two'})
# TypeError: func() missing 1 required positional argument: 'arg3'

# func(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three', 'arg4': 'four'})
# TypeError: func() got an unexpected keyword argument 'arg4'

对于有默认参数的函数

图像,其中只有与字典中的键匹配的参数名的值被更新。

一个与参数名称不匹配的键将导致一个TypeError错误。

def func_default(arg1=1, arg2=2, arg3=3):
    print('arg1 =', arg1)
    print('arg2 =', arg2)
    print('arg3 =', arg3)

func_default(**{'arg1': 'one'})
# arg1 = one
# arg2 = 2
# arg3 = 3

func_default(**{'arg2': 'two', 'arg3': 'three'})
# arg1 = 1
# arg2 = two
# arg3 = three

# func_default(**{'arg1': 'one', 'arg4': 'four'})
# TypeError: func_default() got an unexpected keyword argument 'arg4'

对于具有可变长度参数的函数

如果设置了可变长度的参数,任何具有指定为参数名称以外的键的元素都会被传递给可变长度的参数。

def func_kwargs(arg1, **kwargs):
    print('arg1 =', arg1)
    print('kwargs =', kwargs)

func_kwargs(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three'})
# arg1 = one
# kwargs = {'arg2': 'two', 'arg3': 'three'}

func_kwargs(**{'arg1': 'one', 'arg2': 'two', 'arg3': 'three', 'arg4': 'four'})
# arg1 = one
# kwargs = {'arg2': 'two', 'arg3': 'three', 'arg4': 'four'}

func_kwargs(**{'arg1': 'one', 'arg3': 'three'})
# arg1 = one
# kwargs = {'arg3': 'three'}