zip和*在python中的具体例子

The python docs gives this code as the reverse operation of zip:

>>> x2, y2 = zip(*zipped)

In particular "zip() in conjunction with the * operator can be used to unzip a list". Can someone explain to me how the * operator works in this case? As far as I understand, * is a binary operator and can be used for multiplication or shallow copy...neither of which seems to be the case here.

解释一:

zip(*zipped) means "feed each element of zipped as an argument to zip". zip is similar to transposing a matrix in that doing it again will leave you back where you started.

>>> 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)]
关于*和**的详细解释二:

Although hammar's answer explains how the reversing works in the case of the zip() function, it may be useful to look at argument unpacking in a more general sense. Let's say we have a simple function which takes some arguments:

>>> 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

Instead of directly specifying the arguments, we can create a list (or tuple for that matter) to hold them, and then tell Python to unpack that list and use its contents as the arguments to the function:

>>> arguments = [42, 'insert value here', 3.14] >>> do_something(*arguments) arg1: 42 arg2: insert value here arg3: 3.14

This behaves as normal if you don't have enough arguments (or too many):

>>> 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)

You can use the same construct when defining a function to accept any number of positional arguments. They are given to your function as a tuple:

>>> 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

And of course you can combine the two techniques:

>>> show_args(*arguments) Argument 0: 42 Argument 1: insert value here

You can do a similar thing with keyword arguments, using a double asterix (**) and a dictionary:

>>> 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

And, of course, you can pass keyword arguments through a dictionary:

>>> values = {'name': 'John', 'age': 17} >>> show_kwargs(**values) age = 17 name = John

It is perfectly acceptable to mix the two, and you can always have required arguments and optional extra arguments to a function:

>>> 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>}

If you are taking optional keyword arguments and you want to have default values, remember you are dealing with a dictionary and hence you can use its get() method with a default value to use if the key does not exist:

>>> 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和*在python中的具体例子)