是否有Python方式将一个字典映射到另一个字典?

时间:2020-06-26 15:45:33

标签: python-3.x dictionary

我有一本字典,例如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

3 个答案:

答案 0 :(得分:2)

一个想法是使用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)将为尚不存在的任何密钥返回0int()返回的结果)。


更新问题后更新。不,没有循环就无法做到这一点(您绝对必须来查看键)-但是有一种方式可以做到而无需创建新字典(对于特殊情况{{ 1}};此方法是否有效取决于您的f = abs

f

请注意,在第一个循环中python禁止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} (出于充分的理由!del)。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

您可以考虑使用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}