解压缩和*运算符
python文档给出了这个代码作为zip的反向操作:
>>> x2, y2 = zip(*zipped)
特别是“zip()与*操作符一起可用于解压缩列表”。 有人可以向我解释*操作符在这种情况下的工作原理吗? 据我所知,*是一个二元运算符,可用于乘法或浅拷贝......这两种情况似乎都不是这种情况。
当像这样使用时,*(星号,在一些圈子中也被称为“splat”运算符)是从列表中解压参数的信号。 有关示例的更完整定义,请参见http://docs.python.org/tutorial/controlflow.html#unpacking-argument-lists。
尽管hammar的答案解释了zip()
函数的逆向工作方式,但从更一般的意义上来看看参数拆包可能会有所帮助。 假设我们有一个简单的函数需要一些参数:
>>> def do_something(arg1, arg2, arg3):
... print 'arg1: %s' % arg1
... print 'arg2: %s' % arg2
... print 'arg3: %s' % arg3
...
>>> do_something(1, 2, 3)
arg1: 1
arg2: 2
arg3: 3
我们可以不用直接指定参数,而是为了保存它们而创建一个列表(或元组),然后告诉Python解压该列表并将其内容用作函数的参数:
>>> arguments = [42, 'insert value here', 3.14]
>>> do_something(*arguments)
arg1: 42
arg2: insert value here
arg3: 3.14
如果你没有足够的参数(或者太多),这就像正常情况那样工作:
>>> arguments = [42, 'insert value here']
>>> do_something(*arguments)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/blair/<ipython console> in <module>()
TypeError: do_something() takes exactly 3 arguments (2 given)
定义函数时可以使用相同的构造来接受任意数量的位置参数。 它们作为一个元组被赋予你的函数:
>>> def show_args(*args):
... for index, value in enumerate(args):
... print 'Argument %d: %s' % (index, value)
...
>>> show_args(1, 2, 3)
Argument 0: 1
Argument 1: 2
Argument 2: 3
当然你可以结合这两种技术:
>>> show_args(*arguments)
Argument 0: 42
Argument 1: insert value here
你可以用关键字参数做一个类似的事情,使用双星号( **
)和字典:
>>> def show_kwargs(**kwargs):
... for arg, value in kwargs.items():
... print '%s = %s' % (arg, value)
...
>>> show_kwargs(age=24, name='Blair')
age = 24
name = Blair
而且,当然,您可以通过字典传递关键字参数:
>>> values = {'name': 'John', 'age': 17}
>>> show_kwargs(**values)
age = 17
name = John
将两者混合是完全可以接受的,并且您可以始终为函数提供所需的参数和可选的额外参数:
>>> def mixed(required_arg, *args, **kwargs):
... print 'Required: %s' % required_arg
... if args:
... print 'Extra positional arguments: %s' % str(args)
... if kwargs:
... print 'Extra keyword arguments: %s' % kwargs
...
>>> mixed(1)
Required: 1
>>> mixed(1, 2, 3)
Required: 1
Extra positional arguments: (2, 3)
>>> mixed(1, 2, 3, test=True)
Required: 1
Extra positional arguments: (2, 3)
Extra keyword arguments: {'test': True}
>>> args = (2, 3, 4)
>>> kwargs = {'test': True, 'func': min}
>>> mixed(*args, **kwargs)
Required: 2
Extra positional arguments: (3, 4)
Extra keyword arguments: {'test': True, 'func': <built-in function min>}
如果您正在使用可选的关键字参数并且想要使用默认值,请记住您正在处理字典,因此,如果密钥不存在,则可以使用带有默认值的get()
方法:
>>> def take_keywords(**kwargs):
... print 'Test mode: %s' % kwargs.get('test', False)
... print 'Combining function: %s' % kwargs.get('func', all)
...
>>> take_keywords()
Test mode: False
Combining function: <built-in function all>
>>> take_keywords(func=any)
Test mode: False
Combining function: <built-in function any>
zip(*zipped)
意味着“将每个zipped
元素作为参数提供给zip
”。 zip
与转置矩阵类似,因为再次执行该操作会使您退回到开始的位置。
>>> a = [(1, 2, 3), (4, 5, 6)]
>>> b = zip(*a)
>>> b
[(1, 4), (2, 5), (3, 6)]
>>> zip(*b)
[(1, 2, 3), (4, 5, 6)]
链接地址: http://www.djcxy.com/p/24027.html
上一篇: Unzipping and the * operator
下一篇: Python: yield