【问题标题】:Combining two dictionaries by merging its values in a sorted list通过将其值合并到排序列表中来组合两个字典
【发布时间】:2015-10-07 20:40:44
【问题描述】:

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

  • 生成的字典不应包含任何重复的书名。
  • 应使用内置的 sort() 方法对生成的字典中的每个书名列表进行排序。
  • 解决方案中不能使用内置函数 fromkeys()

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

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())

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

不能导入任何模块。

【问题讨论】:

  • 你的输入dict的数据结构是什么?
  • 我有点困惑,你能举一个 key : value 在你的字典里的例子吗?
  • 您使用的是哪个版本的 Python?字典的 keysvaluesitems 方法返回的值在 Python 2 和 3 之间发生了很大变化,因此假设错误版本的答案可能没有多大帮助。
  • 另外,请用函数的示例输入和预期输出更新帖子
  • 我添加了一个示例输入和预期的输出,但我在帖子中的代码出现格式错误

标签: python string algorithm dictionary key-value


【解决方案1】:
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']}

【讨论】:

    【解决方案2】:

    您的代码中的一些问题 -

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

    2. sorted() 返回排序后的列表,它不进行就地排序。这只会返回排序后的值列表,而不是字典,直接创建字典时需要使用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]

    对于在两个字典中都找到键的情况,您可以添加两个字典的列表,然后将其转换为 set 并返回列表,然后对其进行排序,然后将其分配回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
    

    正如 cmets 中所要求的那样 -

    当一个键在两个字典中时,有没有办法在不使用集合的情况下做到这一点?

    不使用集合的方法是 -

    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
    

    【讨论】:

    • 我怎样才能使函数循环并生成一个包含所有更改值的字典,而不是像现在修复时那样只包含“f”或“d”键的值错误?
    • 当一个键在两个字典中时,有没有办法在不使用集合的情况下做到这一点?
    • 是的,有,但如果没有集合,它会更复杂,而且很可能性能更差
    • 你能告诉我那会怎样吗?我需要知道如何在没有集合的情况下编写此代码,到目前为止,我已将这部分代码更改为 for d1[key] in d2[key]: if d1[key] not in union[key]: union[key].append(d1[key])
    猜你喜欢
    • 2021-04-10
    • 1970-01-01
    • 2023-02-18
    • 2022-07-06
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多