有雾的星号在python

我正在使用itertools.chain以这种方式“扁平”列表的列表:

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

这与说法不同有什么不同:

 uniqueCrossTabs = list(itertools.chain(uniqueCrossTabs)) 

*是“splat”操作符:它将一个列表作为input,并将其展开为函数调用中的实际位置参数。

所以如果uniqueCrossTabs[ [ 1, 2 ], [ 3, 4 ] ] ,那么itertools.chain(*uniqueCrossTabs)itertools.chain([ 1, 2 ], [ 3, 4 ])

这显然不同于传入uniqueCrossTabs 。 就你而言,你有一个列表,你想扁平化; itertools.chain()所做的是将所有传递给它的位置参数的连接返回一个迭代器,其中每个位置参数本身都是可迭代的。

换句话说,你需要将uniqueCrossTabs中的每个列表作为chain()的parameter passing给chain() ,它们将它们链接在一起,但是你没有在单独variables中的列表,所以你使用*运算符来扩展列表成几个列表参数。

正如Jochen Ritzel在评论中指出的那样, chain.from_iterable()更适合于这个操作,因为它假定一个iterable的iterable是可以开始的。 你的代码就变成了:

 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]