Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 制作列表的所有可能组合_Python_List_Combinations - Fatal编程技术网

Python 制作列表的所有可能组合

Python 制作列表的所有可能组合,python,list,combinations,Python,List,Combinations,我需要能够使一个列表,其中包含了一个输入列表的所有可能的组合。 例如,列表[1,2,3]应返回[1[1,2][1,3]2[2,3]3[1,2,3] 列表不必按任何特定顺序排列。在这个网站上,我发现了很多使用itertools的函数,但是当我只需要一个列表时,这些函数就是返回对象。例如: import itertools lst = [1, 2, 3] combs = [] for i in xrange(1, len(lst)+1): combs.append(i) els

我需要能够使一个列表,其中包含了一个输入列表的所有可能的组合。 例如,列表
[1,2,3]
应返回
[1[1,2][1,3]2[2,3]3[1,2,3]
列表不必按任何特定顺序排列。在这个网站上,我发现了很多使用
itertools
的函数,但是当我只需要一个
列表时,这些函数就是返回对象。例如:

import itertools

lst = [1, 2, 3]
combs = []

for i in xrange(1, len(lst)+1):
    combs.append(i)
    els = [list(x) for x in itertools.combinations(lst, i)]
    combs.append(els)
现在
combs
保存此值:

[1, [[1], [2], [3]], 2, [[1, 2], [1, 3], [2, 3]], 3, [[1, 2, 3]]]
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
是的,它与您提供的示例输出略有不同,但在该输出中,您没有列出所有可能的组合

我在列出每个大小的实际列表之前列出了组合的大小,如果您需要的只是组合(没有大小,如示例输出中所示),那么请尝试以下其他版本的代码:

import itertools

lst = [1, 2, 3]
combs = []

for i in xrange(1, len(lst)+1):
    els = [list(x) for x in itertools.combinations(lst, i)]
    combs.extend(els)
现在
combs
保存此值:

[1, [[1], [2], [3]], 2, [[1, 2], [1, 3], [2, 3]], 3, [[1, 2, 3]]]
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]

itertools模块中的函数返回迭代器。要将这些列表转换为列表,只需对结果调用
list()

但是,由于您需要分别调用
itertools.compositions
三次(每种不同长度调用一次),因此您可以使用
list.extend
将迭代器的所有元素添加到最终列表中

请尝试以下操作:

import itertools
in_list = [1, 2, 3]
out_list = []
for i in range(1, len(in_list)+1):
    out_list.extend(itertools.combinations(in_list, i))
out_list = [x[0] if len(x) == 1 else list(x) for x in out_list]
# [1, 2, 3, [1, 2], [1, 3], [2, 3], [1, 2, 3]]
或作为列表:

out_list = [c for i in range(len(in_list)) for c in itertools.combinations(in_list, i+1)]
这些将导致以下列表:

[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
如果需要列表而不是元组,并且要将单长度元组转换为值,可以执行以下操作:

import itertools
in_list = [1, 2, 3]
out_list = []
for i in range(1, len(in_list)+1):
    out_list.extend(itertools.combinations(in_list, i))
out_list = [x[0] if len(x) == 1 else list(x) for x in out_list]
# [1, 2, 3, [1, 2], [1, 3], [2, 3], [1, 2, 3]]
或将单个项目保留为列表:

out_list = map(list, out_list)

您可以使用
itertools解决问题。循环内部的组合

>>> l = [1,2,3]
>>> comb = []
>>> for i in range(len(l)):
...   comb += itertools.combinations(l,i+1)
... 
>>> comb
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
如果您希望将它们列为列表:

>>> comb_list = [ list(t) for t in comb ]
>>> comb_list
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
编辑:组合的第一个参数是iterable,第二个参数是结果元组的长度(在这种情况下,从
1
len(l)


关于组合的更多信息:

模块确实返回生成器而不是列表,但是:

  • 生成器通常比列表更高效(尤其是在生成大量组合时)
  • 当您确实需要时,您总是可以使用
    list(…)
    将生成器转换为列表
itertools的
组合
功能运行良好
,但您需要使用Python 2.6或更高版本:

导入itertools
定义所有_组合(任何_列表):
返回itertools.chain.from_iterable(
itertools.组合(任意列表,i+1)
对于x范围内的i(len(任何_列表)))
然后,您可以将其称为:

#作为一个生成器
所有_组合([1,2,3])#-->
#列表
列表(所有#u组合([1,2,3])#-->[(1,),(2,),(3,),(1,2),(1,3),(2,3),(1,2,3)]
#作为列表的列表
[所有_组合([1,2,3])中l的列表(l)]#-->[1]、[2]、[3]、[1,2]、[1,3]、[2,3]、[1,2,3]]
如果您以前没有使用过生成器,请注意,您可以像列表一样循环使用生成器,例如:

# a generator returned instead of list
my_combinations = all_combinations([1,2,3])

# this would also work if `my_combinations` were a list
for c in my_combinations:
    print "Combo", c

"""
Prints:
  Combo (1,)
  Combo (2,)
  Combo (3,)
  Combo (1, 2)
  Combo (1, 3)
  Combo (2, 3)
  Combo (1, 2, 3)
"""
性能差异可能非常显著。如果比较性能,您会发现生成器的创建速度要快得多:

# as a generator
all_combinations(range(25))  # timing: 100000 loops, best of 3: 2.53 µs per loop

# as a list
list(all_combinations(range(25)))  # timing: 1 loops, best of 3: 9.37 s per loop
请注意,在这两种情况下,迭代所有组合仍然需要一些时间,但这对您来说可能是一个巨大的胜利,特别是如果您在早期找到了您想要的东西

l = [1,2,3]
combs = reduce(lambda x, y: list(itertools.combinations(l, y)) + x, range(len(l)+1), [])

如果您想要一个oneliner。

我认为值得将其他答案浓缩到一个简单的Python 3示例中:

from itertools import chain, combinations

def all_combinations(array):
    return chain(*(list(combinations(array, i + 1)) for i in range(len(array))))
这将返回一个iterable,以查看值:

>>> print(list(all_combinations((1, 2, 3))))
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

这不是OP所问的。@julio.alegria是的,这是OP所问的,我只是编辑了我的答案,效果很好,返回的结果接近我要找的。有没有办法得到一个列表列表而不是元组?@Charles,我刚刚编辑了我的答案,我相信这就是你要问的。别让这些否决票愚弄了你:)我还没来得及扩展我的第一个答案,他们就投了。我不明白为什么@juliomalegria否决了这个,非常粗鲁!答案一开始是不正确的,但奥斯卡修正了答案,现在它工作了。取消否决票。优雅简洁的解决方案+1:)我试过使用这个,但解释器说我不能在非类型上使用iter。你的两个解决方案仍然返回一个元组列表。是的,我需要一个列表列表,而不是元组列表。有没有不使用itertools解决问题的方法?@Charles,你可以不用itertools解决问题,但这会更加困难。将元组转换为列表非常容易,元组几乎与列表完全相同,所以我怀疑您是否真的需要这样做。如果出现错误,请向我们显示不起作用的代码。否则我们无法找出你做错了什么。@Charles-编辑了我的代码,用于将元组转换为列表,以及将单长度元组转换为示例中的值。没有itertools也可以做到这一点,但不会那么简洁。这是否回答了您的问题?