创建嵌套字典,为每个键提供值范围



我对python和处理字典还是个新手。我要得到10本这样的字典

d1 = {'a': 13, 'b':4.53, 'c':3243, 'd':0.2323}
d2 = {'a': 12, 'b':4.3, 'c':373, 'd':0.263}
…
dn = {'a': 16, 'b':9.53, 'c':76843, 'd':13}

我想返回嵌套字典,其中包含每个值的最小值和最大值。这样的

d_out = {'a': {'min': 12,'max': 16},
'b': {'min': 4.3,'max': 9.53},
'c': {'min': 373,'max': 76843},
'd': {'min': 0.2323,'max': 13},
}

假设输入如下:

ds = [{'a': 13, 'b':4.53, 'c':3243, 'd':0.2323},
{'a': 12, 'b':4.3, 'c':373, 'd':0.263},
{'a': 16, 'b':9.53, 'c':76843, 'd':13},]
## or 
# ds = [d1, d2, d3, ...]

你可以在zip/map帮助下使用字典理解:

dict(zip(ds[0],
map(lambda x: {'min': min(x), 'max': max(x)},
zip(*(d.values()
for d in ds)))))

输出:

{'a': {'min': 12, 'max': 16},
'b': {'min': 4.3, 'max': 9.53},
'c': {'min': 373, 'max': 76843},
'd': {'min': 0.2323, 'max': 13}}

比较这个方法和@Dani的Counter技巧。30k个元素的计时:

# dictionary comprehension
5.09 ms ± 202 µs per loop
# Counter trick
112 ms ± 2.65 ms per loop

一种方法是使用collections.Counter并利用相交计算最小值,并集计算最大值的事实:

from collections import Counter
from operator import and_, or_
from functools import reduce
# toy data
dict1 = {'a': 13, 'b': 4.53, 'c': 3243, 'd': 0.2323}
dict2 = {'a': 12, 'b': 4.3, 'c': 373, 'd': 0.263}
dict3 = {'a': 16, 'b': 9.53, 'c': 76843, 'd': 13}
# conver to Counter
d = list(Counter(**di) for di in [dict1, dict2, dict3])
# find intersection i.e min
mi = reduce(and_, d)
# find union i.e max
ma = reduce(or_, d)
# build result dictionary
res = {key: {"min": value, "ma": ma[key]} for key, value in mi.items()}
print(res)

{'a': {'min': 12, 'ma': 16}, 'b': {'min': 4.3, 'ma': 9.53}, 'c': {'min': 373, 'ma': 76843}, 'd': {'min': 0.2323, 'ma': 13}}