【问题标题】:How to pull all the unique combinations from a list of lists如何从列表列表中提取所有唯一组合
【发布时间】:2012-10-06 11:16:42
【问题描述】:

我想遍历列表列表,并从列表中提取所有组合。

我可以通过以下方式做到这一点:

list = [['1','2','3'],['a','b','c'],['x','y','z']]
for itemi in list[0]:
    print itemi
    for itemj in list[1]:
        print itemi+itemj
        for itemk in list[2]:
            print itemi+itemj+itemk

我的问题是我想对 list o' 列表中的不同数量的列表执行此操作。起初只有一个列表,(目前)以 64 个列表结束。

以上示例适用于 3 个列表,实际上所有列表都包含相同的值(0 到 255)。我使用上面的示例只是为了让您可以看到输出应该是什么样子。

我认为必须有更好的方法来解决这个问题,而不必为每个列表大小的列表构建嵌套的 for 循环。

【问题讨论】:

  • 您能否更详细地描述一下“从列表中提取所有组合”是什么意思?
  • 请添加你想要的输出
  • 当然 - 我想创建一组变量来表示列表列表中每个元素的每个组合。在上面的例子中,输出将是 1, 1a, 1ax, 1ay, 1az, 1b, 1bx ... 3b, 3bx, 3by, 3bz, 3c, 3cx, 3cy, 3cz。
  • 13b 三个列表的组合怎么样?
  • 看看PyChecker。它应该给你一个警告你隐藏一个内置的地方。

标签: python list loops


【解决方案1】:

使用itertools.product():

>>> l = [['1','2','3'],['a','b','c'],['x','y','z']]
>>> import itertools
>>> list(itertools.product(*l))
[('1', 'a', 'x'), ('1', 'a', 'y'), ('1', 'a', 'z'), ('1', 'b', 'x'), 
 ('1', 'b', 'y'), ('1', 'b', 'z'), ('1', 'c', 'x'), ('1', 'c', 'y'), 
 ('1', 'c', 'z'), ('2', 'a', 'x'), ('2', 'a', 'y'), ('2', 'a', 'z'), 
 ('2', 'b', 'x'), ('2', 'b', 'y'), ('2', 'b', 'z'), ('2', 'c', 'x'), 
 ('2', 'c', 'y'), ('2', 'c', 'z'), ('3', 'a', 'x'), ('3', 'a', 'y'), 
 ('3', 'a', 'z'), ('3', 'b', 'x'), ('3', 'b', 'y'), ('3', 'b', 'z'), 
 ('3', 'c', 'x'), ('3', 'c', 'y'), ('3', 'c', 'z')]

这还不是您想要的,但很容易实现:

>>> for i in range(len(l)):
...     print(list(itertools.product(*l[:i+1])))
...
[('1',), ('2',), ('3',)]
[('1', 'a'), ('1', 'b'), ('1', 'c'), ('2', 'a'), ('2', 'b'), ('2', 'c'), 
 ('3', 'a'), ('3', 'b'), ('3', 'c')]
[('1', 'a', 'x'), ('1', 'a', 'y'), ('1', 'a', 'z'), ('1', 'b', 'x'), 
 ('1', 'b', 'y'), ('1', 'b', 'z'), ('1', 'c', 'x'), ('1', 'c', 'y'), 
 ('1', 'c', 'z'), ('2', 'a', 'x'), ('2', 'a', 'y'), ('2', 'a', 'z'), 
 ('2', 'b', 'x'), ('2', 'b', 'y'), ('2', 'b', 'z'), ('2', 'c', 'x'), 
 ('2', 'c', 'y'), ('2', 'c', 'z'), ('3', 'a', 'x'), ('3', 'a', 'y'), 
 ('3', 'a', 'z'), ('3', 'b', 'x'), ('3', 'b', 'y'), ('3', 'b', 'z'), 
 ('3', 'c', 'x'), ('3', 'c', 'y'), ('3', 'c', 'z')]

在一个列表中获取所有内容:

>>> result = []
>>> for i in range(len(l)):
...     result.extend(list(itertools.product(*l[:i+1])))
...
>>> result
[('1',), ('2',), ('3',), ('1', 'a'), ('1', 'b'), ('1', 'c'), ('2', 'a'), 
 ('2', 'b'), ('2', 'c'), ('3', 'a'), ('3', 'b'), ('3', 'c'), ('1', 'a', 'x'), 
 ('1', 'a', 'y'), ('1', 'a', 'z'), ('1', 'b', 'x'), ('1', 'b', 'y'), 
 ('1', 'b', 'z'), ('1', 'c', 'x'), ('1', 'c', 'y'), ('1', 'c', 'z'), 
 ('2', 'a', 'x'), ('2', 'a', 'y'), ('2', 'a', 'z'), ('2', 'b', 'x'), 
 ('2', 'b', 'y'), ('2', 'b', 'z'), ('2', 'c', 'x'), ('2', 'c', 'y'), 
 ('2', 'c', 'z'), ('3', 'a', 'x'), ('3', 'a', 'y'), ('3', 'a', 'z'), 
 ('3', 'b', 'x'), ('3', 'b', 'y'), ('3', 'b', 'z'), ('3', 'c', 'x'), 
 ('3', 'c', 'y'), ('3', 'c', 'z')]

得到你想要的确切形状:

>>> sorted(result)
[('1',), ('1', 'a'), ('1', 'a', 'x'), ('1', 'a', 'y'), ('1', 'a', 'z'), 
 ('1', 'b'), ('1', 'b', 'x'), ('1', 'b', 'y'), ('1', 'b', 'z'), ('1', 'c'), 
 ('1', 'c', 'x'), ('1', 'c', 'y'), ('1', 'c', 'z'), ('2',), ('2', 'a'), 
 ('2', 'a', 'x'), ('2', 'a', 'y'), ('2', 'a', 'z'), ('2', 'b'), ('2', 'b', 'x'), 
 ('2', 'b', 'y'), ('2', 'b', 'z'), ('2', 'c'), ('2', 'c', 'x'), ('2', 'c', 'y'), 
 ('2', 'c', 'z'), ('3',), ('3', 'a'), ('3', 'a', 'x'), ('3', 'a', 'y'), 
 ('3', 'a', 'z'), ('3', 'b'), ('3', 'b', 'x'), ('3', 'b', 'y'), ('3', 'b', 'z'), 
 ('3', 'c'), ('3', 'c', 'x'), ('3', 'c', 'y'), ('3', 'c', 'z')]

【讨论】:

  • itertools 来救援! (一如既往)
  • 你能限制它使用少于完整列表的列表吗? (例如,只使用 l[0] 到 1[1]。我可以迭代地剪辑完整列表,直到达到限制并在缩减版本上操作,但我想知道是否有办法在 itertools 库中执行此操作?编辑:哈,打败我!谢谢。另一个很好的学习工具!:) 感谢您的时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多