dicts-python动态编程

dicts-python动态编程,python,combinations,dynamic-programming,Python,Combinations,Dynamic Programming,我有一个清单的dicts;我使用itertools.combinations获取索引和索引组合 list_of_dict = [{1: 'a', 2:'b', 3: 'c', 4: 'd'}, {1: 'b', 2:'b', 3: 'a', 4: 'd'}, {1: 'a', 2:'c', 3: 'd', 4: 'd'}, {1: 'c', 2:'a', 3: 'd', 4: 'b'}] indic

我有一个
清单
dict
s;我使用
itertools.combinations
获取索引和索引组合

list_of_dict = [{1: 'a', 2:'b', 3: 'c', 4: 'd'}, 
                {1: 'b', 2:'b', 3: 'a', 4: 'd'},
                {1: 'a', 2:'c', 3: 'd', 4: 'd'},
                {1: 'c', 2:'a', 3: 'd', 4: 'b'}]
indices = [0, 1, 2, 3]
combinations = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3), 
                (0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3), 
                (0, 1, 2, 3)]
现在我定义了一个
merge
函数,它接受2个
dict
s,实现我的合并逻辑并返回一个
dict
。我对
组合的所有元素执行合并

list_of_dict = [{1: 'a', 2:'b', 3: 'c', 4: 'd'}, 
                {1: 'b', 2:'b', 3: 'a', 4: 'd'},
                {1: 'a', 2:'c', 3: 'd', 4: 'd'},
                {1: 'c', 2:'a', 3: 'd', 4: 'b'}]
indices = [0, 1, 2, 3]
combinations = [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3), 
                (0, 1, 2), (0, 1, 3), (0, 2, 3), (1, 2, 3), 
                (0, 1, 2, 3)]
merge
的调用如下:

candidates = {}
for p in combinations:
    n = 1
    temp_p = None
    c = None
    while (n < (len(p) - 2)):
        c = tuple(list(p)[0:-n]) 
        if c in candidates:
            temp_p = candidates[c]
            break
        else: 
            n += 1
    if temp_p:
        p1 = temp_p
        p2 = p[len(c)]
        candidate[p] = merge(list_of_dict[p1], list_of_dict[p2])
    else:
        candidates[p] = merge(list_of_dict[p[0]], list_of_dict[p[1]])
candidates={}
对于组合中的p:
n=1
温度p=无
c=无
而(n<(len(p)-2)):
c=元组(列表(p)[0:-n])
如果候选人中有c:
temp_p=候选人[c]
打破
其他:
n+=1
如果温度为:
p1=温度
p2=p[len(c)]
候选[p]=合并(目录[p1]的目录[U],目录[p2]的目录[U])
其他:
候选者[p]=合并(主语[p[0]]的列表,主语[p[1]]的列表)
逻辑:如我们所见,当我计算
merge(0,1,2)
时,我可以重用
merge(0,1)
的输出;i、 e.
merge(0,1,2)=merge(merge(0,1,2)
。类似地,对于
merge(0,1,2,3)
我可以重用
merge(0,1,2)

问题:

  • 我不能完全确定上面的代码块是否正确 “逻辑”中描述的内容
  • 有没有一种优雅而有效的方法来实现上述目标
  • 编辑: 合并函数执行以下操作。 如果d1[k]==d2[k],则将d1[k]添加到要返回的新dict中,否则不添加任何内容。 因此,根据给出的示例:

    merge(0,1)
    应该返回:
    {1:None,2:b',3:None,4:d'}

    merge(0,1,2)
    变成merge
    merge({1:None,2:b',3:None,4:d'},{1:a',2:c',3:d',4:d'})
    并且应该返回
    {1:None,2:None,3:None,4:d'}

    这个过程一直持续到所有DICT的组合被合并


    当我们不知道提交给算法的此类词典的初始数量时,这个问题尤为重要。

    此代码将满足您的所有要求:

    from collections import defaultdict
    
    def merge(d1, d2, *dicts):
        new_dict = defaultdict()
        new_dict.update(d1.copy())
    
        for key, value in d2.items():
            if value != new_dict[key]:
                new_dict[key] = None
    
        if dicts:
            new_dict = merge(new_dict, *dicts)
    
        return new_dict
    
    
    for comb in combinations:
        print(merge(*map(list_of_dict.__getitem__, comb)))
    
    首先,我将传递字典留给了
    merge
    ,因为
    dict
    是可变对象,所以在这种情况下,只有它在内存中的引用被传递给函数。您可以使用
    id
    功能轻松检查它。所以,由于这个解决方案比按索引从列表中收集字典更具可读性,所以它更具python风格

    其次,我使用了传递给
    merge
    的第一个字典的
    copy
    ,所以对于其他组合,原始字典保持不变

    正如您所看到的,我使用了
    collections
    包中的
    defaultdict
    ,而不是
    dict
    ,因此如果您的
    d1
    d2
    有不同的键,您可以跳过检查
    new\u dict
    中是否存在键

    最后一个:
    map(list\u of dict.\uu getitem\uuu,comb)
    -这将返回生成器对象(对于python 3.x),其中包含来自
    list\u of dict
    的项,这些项在
    comb
    中索引。(*)
    map
    之前的通配符意味着将其解包为参数,因此,在不实际创建新列表或元组(并在之后解包)的情况下,它只会将项(在本例中是对列表中字典的引用)作为
    merge
    参数生成

    就这样

    提供的代码将打印以下内容:

    defaultdict(None, {1: None, 2: 'b', 3: None, 4: 'd'})
    defaultdict(None, {1: 'a', 2: None, 3: None, 4: 'd'})
    defaultdict(None, {1: None, 2: None, 3: None, 4: None})
    defaultdict(None, {1: None, 2: None, 3: None, 4: 'd'})
    defaultdict(None, {1: None, 2: None, 3: None, 4: None})
    defaultdict(None, {1: None, 2: None, 3: 'd', 4: None})
    defaultdict(None, {1: None, 2: None, 3: None, 4: 'd'})
    defaultdict(None, {1: None, 2: None, 3: None, 4: None})
    defaultdict(None, {1: None, 2: None, 3: None, 4: None})
    defaultdict(None, {1: None, 2: None, 3: None, 4: None})
    defaultdict(None, {1: None, 2: None, 3: None, 4: None})
    
    此外,我已经在20个字典(每个字典len=10000)的列表上测试了这段代码,我还有下一个计时:

  • 生成目录列表:
    15.96887145599976
  • 对每个索引组合应用合并(总共1012个):
    15.6302346700349

  • 你的合并到底在做什么?你能展示一下函数的定义吗?另外,在这个示例中,您期望的输出是什么?@YaroslavSurzhikov添加了merge的描述和一个示例输出。提前感谢您的帮助:-)我会尽快更新我的答案以满足您的要求。顺便说一句,这对
    merge
    accept indicies as agment很重要,还是像我已经实现的那样,它们可以是字典?字典的实际大小太大,因此我在实现中使用了索引。再次感谢你!嘿,我刚刚用解释更新了我的答案。对不起,如果你遇到错误,英语不是我的母语谢谢你的详细解释!那真的很有帮助@okkhoy很高兴我能帮上忙