有没有办法获得字典中或列表中值之间重叠的所有组合

Is there a way to get all combinations of overlap between values in dictionary, or from within a list

我有几个列表

A =['D','KIT','SAP'],
B= ['F','G','LUFT','SAP'],
C= ['I','SAP'],
D= ['SAP','LUF','KIT'],
F= ['SAP','LUF','KIT','HASS']

我将它们组合传递给字典。例如,我将列表 A 和 B 作为键 'AB' 加入到我的新字典中,并将两个列表中的值(如值列表)附加到该键 'AB'.

my_dict={"AB":[['D','KIT','SAP'],['F','G','LUFT','SAP']]}

我的目标是在多个组合中获得列表之间的重叠。为此,我可以使用下面的衬垫。

   for k,v in my_dict.items():
        print(k,list(set.intersection(*[set(x) for x in v])))

AB ['SAP']

但是,这里的问题是当我有更多的列表和更多的组合时,手动定义一个包含所有可能组合的字典是很乏味的。

目的是实现所有可能的列表组合。从上述示例中,我有以下列表组合。在这种情况下,这将是 5*5 +1 = 26 种组合。 最后,我想得到以下每个组合的重叠。

   AB, AC, AD, AF
    ABC, ABD, ABF
    ABCD, ABCDF
    ABCDF
BC, BD, BF
DF, DC
FC

问题是我怎样才能以 pythonic 方式实现它。非常感谢任何建议。

附带说明一下,如果列表本身可以实现这种重叠组合,我不希望在两者之间使用字典。

谢谢

看看itertools.combinations。它 returns 给定可迭代的给定长度的所有可能组合。您必须遍历所有可能的长度。

import itertools

lists = [A, B, C, D, E, F]

combinations = []

for l in range(2, len(lists) + 1):
    combinations += itertools.combinations(lists, l)

combinations 将是一个元组列表,其中包含至少两个列表的所有可能组合。

[在评论中交流后编辑解决方案]

import itertools as it

A =['D','KIT','SAP'],
B= ['F','G','LUFT','SAP'],
C= ['I','SAP'],
D= ['SAP','LUF','KIT'],
F= ['SAP','LUF','KIT','HASS']

master_dict = dict(A=A, B=B, C=C, D=D, F=F)
for i in range(len(master_dict)):
    for combo in it.combinations(master_dict.keys(), i):
        new_key = "".join(combo)
        print(combo)
        if (len(combo)>1):
            mixed_dict[new_key] = set.intersection(*[set(master_dict[c][0]) for c in combo])
            print("---->" + str(mixed_dict[new_key]))

... 带有一些注释掉的打印语句向您展示发生了什么。在脚本的末尾,您有一个 new_dict,如下所示:

我没有故意添加长度为 1 的组合,但您可以删除上面的 if() 条件以恢复它们。

这是使用@Marco Breemhaar 的答案实现的字典创建,我使用他的解决方案创建了您想要的字典。这是代码:

import itertools

import string
alphabet_string = string.ascii_uppercase
alphabet_list = list(alphabet_string)


A =['D','KIT','SAP']
B= ['F','G','LUFT','SAP']
C= ['I','SAP']
D= ['SAP','LUF','KIT']
E= ['SAP','LUF','KIT','HASS']

lists = [A, B, C, D, E]

combinations = []

for l in range(2, len(lists) + 1):
    combinations += itertools.combinations(lists, l)

alp_comb = []
for l in range(2, len(alphabet_list) + 1):
    alp_comb += itertools.combinations(alphabet_list[:len(lists)], l)

key_list = []
for alp_elem in alp_comb:
    key_name = ""
    for elem in alp_elem:
        key_name += elem
    key_list.append(key_name)
    key_name = None


res_dict = dict()
for key, elem in zip(key_list, combinations):
    res_dict[key] = list(elem)
print(res_dict)

为了开始解决这个问题,我会把给你的列表变成字典。这是为了方便地引用列表的名称及其值。

和sagi评论的一样,你列出的组合并没有给出所有的组合。因此,我使用包 itertools 和 中的代码来获取所有可能的组合并对其进行稍微修改以仅给出大于一个列表长度的结果。

然后我们需要将这些添加到 my_dict。我使用了来自 geeksforgeeks https://www.geeksforgeeks.org/python-program-to-convert-a-tuple-to-a-string/ 的代码片段,将元组转换为我们用作 my_dict 的键的字符串。同时,我们正在构建一个列表以添加到那些提到的键中。

然后我们就用你的函数来查找交叠的元素。我们应该期望有 2^(len(listsdict)) - len(listsdict) - 1,因为我们不排除任何元素,只排除一个元素。希望这能解决问题。

from itertools import combinations

#turn list into a dictionary of lists
listsdict = {
    'A' : ['D','KIT','SAP'],
    'B' : ['F','G','LUFT','SAP'],
    'C' : ['I','SAP'],
    'D' : ['SAP','LUF','KIT'],
    'F' : ['SAP','LUF','KIT','HASS']
}

my_dict = {}

#from https://www.geeksforgeeks.org/python-program-to-convert-a-tuple-to-a-string/
def convertTuple(tup):
    str = ''
    list = []
    for item in tup:
        str = str + item
        list += [listsdict[item]]
    my_dict[str] = list
    return str

#from 
for L in range(0, len(listsdict)+1):
    for subset in combinations(listsdict, L):
        if len(subset) > 1:
            convertTuple(subset)

#OP's functions
for k,v in my_dict.items():
    print(list(set.intersection(*[set(x) for x in v])))

感谢所有解决方案。每个解决方案都有帮助。但是,其中 none 正是我要找的答案。尽管如此,所有这些都在一定程度上帮助我找到了正确的解决方案。发帖给大家可能会有帮助。

我首先需要为 5 个列表创建 26 种组合。 初始列表

A =['D','KIT','SAP']
B= ['F','G','LUFT','SAP']
C= ['I','SAP']
D= ['SAP','LUF','KIT']
E= ['SAP','LUF','KIT','HASS']

做了一个列表列表

lists = [A, B, C, D, E]

将称为组合的空列表定义为@marco 的解决方案。并根据列表的长度添加所有可能的组合,加一。这些组合是我们最终字典中的值。

 combinations =[]
    for l in range(2, len(lists) + 1):
        combinations += itertools.combinations(lists, l)

之后用列表的列表中的键和值定义一个字典。从这里我部分采用了@butterflyknife 的解决方案。

master_dict = dict(A=A, B=B, C=C, D=D, F=F)

对于最终字典的键,我们首先定义了一个空列表。然后使用 join.

填充组合
key_list    = []
for i in range(2,len(master_dict) +1):
    for combo in it.combinations(master_dict.keys(), i):
        new_key = "".join(combo)
        if (len(combo)>1):
            key_list.append(new_key)

现在,同时具有键和值。我们填充最终字典。

final_dict = dict()
for key, elem in zip(key_list, combinations):
    final_dict[key] = list(elem)
   

这部分是找到重叠并将它们转换为数据框。

overlap_list  = []
dfs = []
for k,v in final_dict.items():
    overlap = list(set.intersection(*[set(x) for x in v]))
    overlap_list.append(overlap)
     #print(overlap, sep=", ")
    dct  ={ 'overlap':overlap,'number of overlapps':len(overlap),
              'overlap models':k}
    dfs.append(dct)
df          = pd.DataFrame.from_dict(dfs)