我被给予一个列表的列表 s
:
s = [["a1", "A"], ["b4", "B"], ["a3", "A"], ["d6", "D"], ["c4", "C"]]
(注意,列表中的元素不一定以相同字母开头。为方便起见,我在此修改了数据。)
我的目标是按其第二个元素将每个列表排序到一个类别,并通过在每个类别中选择最多一个元素来获取所有可能的组合。
我首先将列表的列表哈希到一个字典中:
dic = {i[1]: [] for i in s}
for i in s:
# set the value of the first item key to the second item
dic[i[1]].append(i[0])
dic
>>> {'A': ['a1', 'a3'], 'B': ['b4'], 'C': ['c4'], 'D': ['d6']}
所有可能的组合数,也就是集合
s
的幂集的长度应该返回 23
:{'a1'},
{'a3'},
{'b4'},
{'c4'},
{'d6'},
{'a1', 'b4'},
{'a1', 'c4'},
{'a1', 'd6'},
{'a3', 'b4'},
{'a3', 'c4'},
{'a3', 'd6'},
{'b4', 'c4'},
{'b4', 'd6'},
{'c4', 'd6'},
{'a1', 'b4', 'c4'},
{'a1', 'b4', 'd6'},
{'a1', 'c4', 'd6'},
{'a3', 'b4', 'c4'},
{'a3', 'b4', 'd6'},
{'a3', 'c4', 'd6'},
{'b4', 'c4', 'd6'},
{'a1', 'b4', 'c4', 'd6'},
{'a3', 'b4', 'c4', 'd6'}
我最初想要使用多个 for
循环,但是因为我无法保证我的 s
中会有多少个 key
(这也会将我的时间复杂度提高到 O(N^x)),所以我使用了 itertools.chain
和 itertools.combinations
,参考了这篇文章:
def powerset(s:list):
return chain.from_iterable(combinations(s, r) for r in range(1, len(s)+1))
问题在于这种方法只考虑单个列表中的元素,忽略了约束条件:“最多只能从每个列表中取一个元素”。将列表扁平化将忽略分类,因此我没有尝试这样做。
欢迎提供任何解决此问题的见解。