我正在使用itertools.chain按照以下方式“展平”一个列表的列表:
uniqueCrossTabs = list(itertools.chain(*uniqueCrossTabs))
这与说什么不同:
uniqueCrossTabs = list(itertools.chain(uniqueCrossTabs))
*
是"展开"操作符:它将类似列表的可迭代对象作为输入,并在函数调用中将其扩展为实际的位置参数。
因此,如果uniqueCrossTabs
是[[1, 2], [3, 4]]
,那么itertools.chain(*uniqueCrossTabs)
与itertools.chain([1, 2], [3, 4])
相同。
这显然不同于只传递uniqueCrossTabs
。在您的情况下,您有一个要展开的列表,而itertools.chain()
的作用是返回一个迭代器,该迭代器在您传递给它的所有位置参数的连接上迭代,其中每个位置参数本身都是可迭代的。
换句话说,您想将uniqueCrossTabs
中的每个列表作为参数传递给chain()
,它将把它们链接在一起,但您没有将列表存储在单独的变量中,因此使用*
运算符将列表的列表展开为几个列表参数。
chain.from_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]
def func(a, b, *args):
。在同样的思路下,另一个重要的应用是在函数定义中:def func(a, b, *args):
。更多信息请参见此答案。 - ASL
**
运算符--它与*
的作用相同,只不过是用于关键字参数。 - Sean Vieira