[英]Making all possible combinations of a list
I need to be able to make a list that contains all possible combinations of an inputted list.我需要能够制作一个包含输入列表的所有可能组合的列表。 For example the list
[1,2,3]
should return [1 [1,2] [1,3] 2 [2,3] 3 [1,2,3]]
The list doesn't have to be in any particular order.例如列表
[1,2,3]
应该返回[1 [1,2] [1,3] 2 [2,3] 3 [1,2,3]]
该列表不必在任何特定顺序。 On this site I've found lots of functions using the itertools
but those are returning objects when I need just a list
.在这个站点上,我发现了很多使用
itertools
的函数,但是当我只需要一个list
时,它们会返回对象。
Simply use itertools.combinations
.只需使用
itertools.combinations
。 For example:例如:
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)
Now combs
holds this value:现在
combs
持有这个值:
[1, [[1], [2], [3]], 2, [[1, 2], [1, 3], [2, 3]], 3, [[1, 2, 3]]]
Yes, it's slightly different from the sample output you provided, but in that output you weren't listing all possible combinations.是的,它与您提供的示例输出略有不同,但在该输出中您并未列出所有可能的组合。
I'm listing the size of the combination before the actual list for each size, if what you need is simply the combinations (without the size, as it appears in your sample output) then try these other version of the code:我在每个尺寸的实际列表之前列出了组合的尺寸,如果您需要的只是组合(没有尺寸,如您的示例输出中所示),请尝试这些其他版本的代码:
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)
Now combs
holds this value:现在
combs
持有这个值:
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
The itertools
module indeed returns generators instead of lists, but: itertools
模块确实返回生成器而不是列表,但是:
list(...)
when you really need to.list(...)
将生成器转换为列表。 The chain
and combinations
functions of itertools
work well , but you need to use Python 2.6 or greater: itertools
的chain
和combinations
函数运行良好,但需要使用Python 2.6 或更高版本:
import itertools
def all_combinations(any_list):
return itertools.chain.from_iterable(
itertools.combinations(any_list, i + 1)
for i in xrange(len(any_list)))
You can then call this as such:然后你可以这样调用它:
# as a generator
all_combinations([1,2,3]) # --> <itertools.chain at 0x10ef7ce10>
# as a list
list(all_combinations([1,2,3])) # --> [(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
# as a list of lists
[list(l) for l in all_combinations([1,2,3])] # --> [[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
If you haven't used generators before, note that you loop through them as if they were a list, such as this:如果您之前没有使用过生成器,请注意您将它们当作一个列表来循环,例如:
# 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)
"""
The performance difference can be dramatic.性能差异可能是巨大的。 If you compare the performance you'll see that the generator is much faster to create:
如果比较性能,您会发现生成器的创建速度要快得多:
# 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
Note that it would still take some time to iterate through all the combinations in either case, but it can be a big win for you especially if you find what you're looking for early on.请注意,在任何一种情况下,遍历所有组合仍然需要一些时间,但这对您来说可能是一个巨大的胜利,尤其是如果您很早就找到了想要的东西。
The functions from the itertools module return iterators. itertools 模块中的函数返回迭代器。 All you need to do to convert these into lists is call
list()
on the result.将这些转换为列表所需要做的就是对结果调用
list()
。
However, since you will need to call itertools.combinations
three separate times (once for each different length), you can just use list.extend
to add all elements of the iterator to your final list.但是,由于您需要调用
itertools.combinations
三次(每个不同的长度调用一次),因此您可以使用list.extend
将迭代器的所有元素添加到最终列表中。
Try the following:请尝试以下操作:
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))
Or as a list comprehension:或者作为列表理解:
out_list = [c for i in range(len(in_list)) for c in itertools.combinations(in_list, i+1)]
These will result in the following list:这些将导致以下列表:
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
If you want lists instead of tuples, and to convert the single length tuples to just the value, you can do the following:如果您想要列表而不是元组,并将单长度元组转换为值,您可以执行以下操作:
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]]
Or to leave the single items as lists:或者将单个项目保留为列表:
out_list = map(list, out_list)
You could solve your problem using itertools.combinations
inside of a loop:您可以在循环内使用
itertools.combinations
解决您的问题:
>>> 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)]
And if you want them as a list:如果您希望将它们作为列表:
>>> comb_list = [ list(t) for t in comb ]
>>> comb_list
[[1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
EDIT: The first parameter of combinations is the iterable and the second one is the length of the resulting tuples (in this case, going from 1
to len(l)
).编辑:组合的第一个参数是可迭代的,第二个参数是生成的元组的长度(在这种情况下,从
1
到len(l)
)。
More about combinations: http://docs.python.org/library/itertools.html#itertools.combinations关于组合的更多信息: http : //docs.python.org/library/itertools.html#itertools.combinations
l = [1,2,3]
combs = reduce(lambda x, y: list(itertools.combinations(l, y)) + x, range(len(l)+1), [])
If you want a oneliner.如果你想要一个单线。
I think it's worth boiling down the other answers here into a simple Python 3 example:我认为值得将这里的其他答案归结为一个简单的 Python 3 示例:
from itertools import chain, combinations
def all_combinations(array):
return chain(*(list(combinations(array, i + 1)) for i in range(len(array))))
This returns an iterable, to view the values:这将返回一个可迭代的,以查看值:
>>> print(list(all_combinations((1, 2, 3))))
[(1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.