【问题标题】:Is there a Pythonic way to map a dictionary to another dictionary?有没有一种 Pythonic 方法可以将一个字典映射到另一个字典?
【发布时间】:2020-06-26 15:45:33
【问题描述】:

我有一本字典,比如d = {-1: 10, 0: 20, 1: 30, 2: 40},其中键 k 是某个标签,值对应于计数的数量。我有一些函数f(x),让我们使用f(x)=|x|,我想创建另一个字典d2,这样d2 = {f(x): #counts f(x)} 的所有x 值都是原始字典中的键。请注意,f 不是单射的,所以f(-1)=f(1)。有没有一种(Pythonic)方法可以做到这一点,而无需从头开始显式循环和构造d2

在示例中,所需的字典是 d2 = {1: 40, 0:20, 2:40}

编辑:我目前的解决方案

def map_dictionary(d, f):
    d2 = {}
    for k in d:
        if f(k) in d2:
            d2[f(k)] += d[k]
        else:
            d2[f(k)] = d[k]
    return d2

【问题讨论】:

    标签: python-3.x dictionary


    【解决方案1】:

    一个想法是使用defaultdict:

    from collections import defaultdict
    
    d = {-1: 10, 0: 20, 1: 30, 2: 40}
    f = abs
    d2 = defaultdict(int)
    for k, v in d.items():
        d2[f(k)] += v
    
    print(d2)  # defaultdict(<class 'int'>, {1: 40, 0: 20, 2: 40})
    

    defaultdict(int) 将为尚不存在的任何密钥返回 0(这是 int() 返回的内容)。


    更新问题后更新。不,没有循环就没有办法做到这一点(你绝对必须查看键) - 但是有一种方法可以在不创建新字典的情况下做到这一点(这里是特殊情况@987654327仅限@;这取决于您的f 这种方法是否有效:

    d = {-1: 10, 0: 20, 1: 30, 2: 40}
    
    neg_keys = []
    for k, v in d.items():
        if k < 0:
            neg_keys.append(k)
            d[-k] = d.get(-k, 0) + v
    
    for k in neg_keys:
        del d[k]
    
    print(d)  # {0: 20, 1: 40, 2: 40}
    

    请注意,python 在第一个循环中禁止 del(有充分的理由!RuntimeError: dictionary changed size during iteration)。

    【讨论】:

      【解决方案2】:

      collections.Counter 无需添加任何内容即可做到这一点:

      from collections import Counter
      
      d = {-1: 10, 0: 20, 1: 30, 2: 40}
      
      d2 = Counter([abs(x) for x, y in d.items() for i in range(y)])
      print(d2)  # Counter({1: 40, 2: 40, 0: 20})
      

      【讨论】:

        【解决方案3】:

        您可以考虑使用dict comprehension

        def f(x):
            return abs(x)
        
        d = {-1: 10, 0: 20, 1: 30, 2: 40}
        
        d2 = { 
            f(key): d[f(key)] + d[key] if 
            f(key) != key and f(key) in d.keys() 
            else d[key]
            for key in sorted( d.keys(), reverse=True ) 
        }
        
        print(d2)
        #{2: 40, 1: 40, 0: 20}
        

        【讨论】:

        • 编辑了我的答案,因为初稿不正确。
        猜你喜欢
        • 1970-01-01
        • 2019-08-27
        • 1970-01-01
        • 1970-01-01
        • 2014-02-17
        • 2021-12-11
        • 1970-01-01
        • 2017-07-07
        • 1970-01-01
        相关资源
        最近更新 更多