foggy on asterisk in python

I'm using itertools.chain to "flatten" a list of lists in this fashion:

uniqueCrossTabs = list(itertools.chain(*uniqueCrossTabs))

how is this different than saying:

uniqueCrossTabs = list(itertools.chain(uniqueCrossTabs))

* is the "splat" operator: It takes a list as input, and expands it into actual positional arguments in the function call.

So if uniqueCrossTabs was [ [ 1, 2 ], [ 3, 4 ] ] , then itertools.chain(*uniqueCrossTabs) is the same as saying itertools.chain([ 1, 2 ], [ 3, 4 ])

This is obviously different from passing in just uniqueCrossTabs . In your case, you have a list of lists that you wish to flatten; what itertools.chain() does is return an iterator over the concatenation of all the positional arguments you pass to it, where each positional argument is iterable in its own right.

In other words, you want to pass each list in uniqueCrossTabs as an argument to chain() , which will chain them together, but you don't have the lists in separate variables, so you use the * operator to expand the list of lists into several list arguments.

As Jochen Ritzel has pointed out in the comments, chain.from_iterable() is better-suited for this operation, as it assumes a single iterable of iterables to begin with. Your code then becomes simply:

uniqueCrossTabs = list(itertools.chain.from_iterable(uniqueCrossTabs))

它将序列分割为函数调用的单独参数。

>>> def foo(a, b=None, c=None):
...   print a, b, c
... 
>>> foo([1, 2, 3])
[1, 2, 3] None None
>>> foo(*[1, 2, 3])
1 2 3
>>> def bar(*a):
...   print a
... 
>>> bar([1, 2, 3])
([1, 2, 3],)
>>> bar(*[1, 2, 3])
(1, 2, 3)

只是解释概念/使用它的另一种方式。

import random

def arbitrary():
    return [x for x in range(1, random.randint(3,10))]

a, b, *rest = arbitrary()

# a = 1
# b = 2
# rest = [3,4,5]
链接地址: http://www.djcxy.com/p/53630.html

上一篇: (一元)操作符在这个Ruby代码中做了什么?

下一篇: 在python上有星号