将列表分成两个列表的所有可能性 [英] All possibilities to split a list into two lists
问题描述
我有一个包含一些元素的列表,并且想要遍历所有可能的方式将该列表分为两个列表.我的意思是所有组合,因此顺序并不重要(即元素1和3可以在一个列表中,元素2可以在另一个列表中).目前,我这样做是这样的,其中facs
是我的初始列表:
I have a list with some elements and want to iterate over all possible ways to divide this list into two lists. By that I mean all combinations, so the order doesn't matter (i.e. Element 1 and 3 could be in the one list and Element 2 in the other). Currently I do it like this, where facs
is my initial list:
patterns = []
for i in range(2**(len(facs)-1)):
pattern = []
for j in range((len(facs)-1)):
pattern.append(i//(2**j)%2)
patterns.append(pattern)
for pattern in patterns:
l1 = [facs[-1]]
l2 = []
for i in range(len(pattern)):
if pattern[i] == 1:
l1.append(facs[i])
else:
l2.append(facs[i])
因此,我基本上创建了一个长度为2^(len(facs)-1)
的列表,并用一和零的每种可能组合填充它.然后我用facs
'覆盖'每个模式,除了facs
的最后一个元素总是在l1
中,否则我将获得两次结果,因为我处理两个列表相同,无论如何列表是l1
或l2
.
So I basically create a list of length 2^(len(facs)-1)
and fill it with every possible combination of ones and zeros. I then 'overlay' every pattern with facs
, except for the last element of facs
which is always in l1
, as I'd otherwise get every result twice, as I handle two lists the same, no matter what lists is l1
or l2
.
是否有更快,更优雅(更短/更pythonic)的方法来实现?
Is there a faster and more elegant (shorter/more pythonic) way to do this?
推荐答案
itertools
具有product()
可用于生成掩码,而izip()
可将列表结合起来以便于过滤.另外,由于它们返回迭代器,因此不会占用太多内存.
itertools
has product()
which could be used to generate the masks and izip()
which could combine the lists for easy filtering. As a bonus, since they return iterators, they don't use much memory.
from itertools import *
facs = ['one','two','three']
l1 = []
l2 = []
for pattern in product([True,False],repeat=len(facs)):
l1.append([x[1] for x in izip(pattern,facs) if x[0]])
l2.append([x[1] for x in izip(pattern,facs) if not x[0]])
这篇关于将列表分成两个列表的所有可能性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!