我有列表a
:
a = [0,1,2,3,4,5]
然后我创建此列表的所有三元素组合。结果在子列表中分组,因为它以二进制3位字符串的形式与等效项匹配。例如,结果[0,4,5]
对应于序列001
,因为每个偶数对应于0,奇数对应于。
我与评论一起使用的代码:
import itertools as it
import itertools
# I create three-element combinations of zeros and ones
combinations_3bit = list(map(list, itertools.product([0,1], repeat=3)))
# output: [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]
# I create a list of strings with values from the list `3bit_combinations`
a=[]
for i in range(len(combinations_3bit)):
a2 =''.join(map(str, [1 if x%2 else 0 for x in combinations_3bit[i]]))
a.append(a2)
# output: ['000', '001', '010', '011', '100', '101', '110', '111']
# I remove repetitions in pairs of type 001 with 100, 011 with 110, etc.
combinations_3bit_without_repetition = [v for k, v in enumerate(a) if v[::-1] not in a[:k]]
# output: ['000', '001', '010', '011', '101', '111']
b = [0,1,2,3,4,5]
good = []
for i in range(len(combinations_3bit_without_repetition)):
c=[]
for u in it.combinations(b, 3):
u1 = list(u)
y =''.join(map(str, [1 if x%2 else 0 for x in u1]))
if y == combinations_3bit_without_repetition[i]:
c.append(u1)
good.append(c)
# output: [[[0, 2, 4]], [[0, 2, 3], [0, 2, 5], [0, 4, 5], [2, 4, 5]], [[0, 1, 2], [0, 1, 4], [0, 3, 4], [2, 3, 4]], [[0, 1, 3], [0, 1, 5], [0, 3, 5], [2, 3, 5]], [[1, 2, 3], [1, 2, 5], [1, 4, 5], [3, 4, 5]], [[1, 3, 5]]]
这可以更好,更经济地解决吗?
因为上面的解决方案似乎是“周围”,例如函数it.combinations
在列表i
中的每个索引combinations_3bit_without_repetition
之后返回所有可能的组合,然后条件仅筛选匹配那些。对于大型列表,此解决方案很弱;)
答案 0 :(得分:3)
有一种更好的方法可以生成所需的二进制字符串:
import itertools
strings = ['{0:03b}'.format(i) for i in range(8)]
b = [0,1,2,3,4,5]
combinations = [list(x) for x in itertools.combinations(b, 3)]
dct = {}
for x in combinations:
y = ''.join(str(j%2) for j in x)
if y in dct:
dct[y].append(x)
else:
dct[y] = [x]
print(dct)
输出:
{'010': [[0, 1, 2], [0, 1, 4], [0, 3, 4], [2, 3, 4]], '011': [[0, 1, 3], [0, 1, 5], [0, 3, 5], [2, 3, 5]], '001': [[0, 2, 3], [0, 2, 5], [0, 4, 5], [2, 4, 5]], '000': [[0, 2, 4]], '101': [[1, 2, 3], [1, 2, 5], [1, 4, 5], [3, 4, 5]], '100': [[1, 2, 4]], '110': [[1, 3, 4]], '111': [[1, 3, 5]]}
检查这是否符合您的需要。它创建一个字典,其中每个键都是长度为3的二进制字符串,每个值都是与二进制字符串匹配的组合数组。
答案 1 :(得分:2)
以下是使用itertools.groupby
和b
的{{1}}解决方案:
combinations_3bit_without_repetition
打印:
def binarize(x):
return ''.join(map(str, map((1).__and__, x)))
srted = sorted(itertools.combinations(b, 3), key=binarize)
allowed = set(combinations_3bit_without_repetition)
result = [list(grp) for bn, grp in itertools.groupby(srted, binarize) if bn in allowed]
print(result)