通过将其值合并到排序列表中来组合两个字典

Combining two dictionaries by merging its values in a sorted list

我在编写一个函数 union_collections 时遇到问题,该函数使用两个字典(d1 和 d2)来表示两个藏书集。该函数生成一个新字典,其中包含 d1 或 d2 中存在的所有书籍,同时保持以下规则:

这些是用于测试的样本集合:

collection1 = \
         {'f':['flatland', 'five minute mysteries', 'films of the 1990s', 'fight club'],
         't':['the art of computer programming', 'the catcher in the rye'],
         'p':['paradise lost', 'professional blackjack', 'paradise regained'],
         'c':['calculus in the real world', 'calculus revisited', 'cooking for one'],
         'd':['dancing with cats', 'disaster at midnight']}

collection2 = \
        {'f':['flatland', 'films of the 1990s'],
         'a':['a brief history of time', 'a tale of two cities'],
         'd':['dealing with stress', 'dancing with cats'],
         't':['the art of computer programming', 'the catcher in the rye'],
         'p':['power and wealth', 'poker essentials', 'post secret'],
         'c':['cat couples', 'calculus', 'calculus revisited',
              'cooking for one', 'calculus in the real world', 'cooking made easy']}`

一个例子:unique_collections(collection1, collection2) 应该产生:

{'f' : ['fight club' , 'films of the 1990s', 'five minute mysteries', 'flatland'],
 't' : ['the art of computer programming', 'the catcher in the rye'],
 'p' : ['paradise lost' , 'paradise regained', 'poker essentials', 'post secret' , 'power and wealth', 'professional blackjack'],
 'c' : ['calculus' , 'calculus in the real world' , 'calculus revisited' , 'cat couples', 'cooking for one', 'cooking made easy'],
 'd' : ['dancing with cats' , 'dealing with stress' , 'disaster at midnight'],
 'a' : ['a brief history of time' , 'a tale of two cities']}`

到目前为止我写了:

def union_collections(d1, d2):
    union = {}

    for key in d1 or d2:
        if key in d1 and key not in d2: # if the key is only in d1
            union[key] = d1[val]

        if key in d2 and key not in d1: #
            union[key] = d2[val]

        if key in d1 and key in d2:
            union = dict(list(d1.items()) + list(d2.items()))

    return sorted(union.values())

此功能不起作用,我不知道如何修复它以符合以下要求。

无法导入任何模块。

def union_collections(d1, d2):
    return { k: sorted(list(set(d1.get(k, []) + d2.get(k, []))))
             for k in set(d1.keys() + d2.keys()) }

同上,但试图提高可读性:

def union_collections(d1, d2):
    return { k: sorted(
                    list(
                        set(
                            d1.get(k, []) + d2.get(k, [])
                        )
                    )
                )
             for k in set(d1.keys() + d2.keys()) }

输出:

{'a': ['a brief history of time', 'a tale of two cities'],
 'c': ['calculus',
       'calculus in the real world',
       'calculus revisited',
       'cat couples',
       'cooking for one',
       'cooking made easy'],
 'd': ['dancing with cats', 'dealing with stress', 'disaster at midnight'],
 'f': ['fight club',
       'films of the 1990s',
       'five minute mysteries',
       'flatland'],
 'p': ['paradise lost',
       'paradise regained',
       'poker essentials',
       'post secret',
       'power and wealth',
       'professional blackjack'],
 't': ['the art of computer programming', 'the catcher in the rye']}

您的代码中存在一些问题 -

  1. 当你做 - union = dict(list(d1.items()) + list(d2.items())) - 不要认为这是有效的,你不能添加字典。也不需要,这对您的要求没有意义。

  2. sorted() returns 排序列表,它不进行就地排序。这只是 return 排序的值列表,而不是字典,您需要在直接创建字典时使用 list.sort()sorted() 函数。

  3. for key in d1 or d2 - 这只会迭代 d1 中的键,您需要使用 set(d1.keys()).union(d2.keys()) .

  4. d1[val] (d2[val]) - 不正确,没有 val 变量,请改用 d1[key]

对于一个key在两个字典中都存在的情况,可以把两个字典的list相加,然后转成set,再转成list,排序后赋值回union 词典。示例 -

def union_collections(d1, d2):
    union = {}

    for key in set(d1.keys()).union(d2.keys()):
        if key in d1 and key not in d2: # if the key is only in d1
            union[key] = d1[key]

        if key in d2 and key not in d1: 
            union[key] = d2[key]

        if key in d1 and key in d2:
            union[key] = sorted(list(set(d1[key] + d2[key])))

    return union

正如评论中所问 -

for when a key is in both dictionaries, is there a way to do this without the use of sets?

不使用集合的方法是 -

def union_collections(d1, d2):
    union = {}

    for key in set(d1.keys()).union(d2.keys()):
        if key in d1 and key not in d2: # if the key is only in d1
            union[key] = d1[key]

        if key in d2 and key not in d1: 
            union[key] = d2[key]

        if key in d1 and key in d2:
            y = []
            union[key] = y
            for x in d1[key]:
                y.append(x)
            for x in d2[key]:
                if x not in y:
                    y.append(x)
            y.sort()

    return union