两个字典
可以使用嵌套循环的 字典推导式:
{(k1,k2):v1*v2 for k1,v1 in region.items() for k2,v2 in gender.items()}
因此我们为每个region
中的k1,v1
和每个gender
中的k2,v2
构造一个字典元素,其键为(k1,k2)
,映射到v1*v2
。
这样生成:
>>> {(k1,k2):v1*v2 for k1,v1 in region.items() for k2,v2 in gender.items()}
{('north', 'female'): 0.13999999999999999, ('west', 'female'): 0.13999999999999999, ('east', 'female'): 0.35, ('south', 'male'): 0.03, ('north', 'male'): 0.06, ('east', 'male'): 0.15, ('south', 'female'): 0.06999999999999999, ('west', 'male'): 0.06}
你看到的是0.13999...
而不是0.14
,这是由于浮点数的四舍五入误差导致的,与字典理解本身无关。
任意数量的字典
也可能出现您想要计算任意数量的字典的笛卡尔积的情况(请注意,由于内存限制,这将呈指数增长,因此字典数量肯定受限)。在这种情况下,您可以使用以下过程:
from operator import mul, getitem
from functools import reduce
from itertools import product, starmap
def cartesian_dictionary(*args,fold=mul):
return { ks : reduce(fold,starmap(getitem,zip(args,ks)))
for ks in product(*args) }
导致:
>>> cartesian_dictionary({'east': 0.5, 'north': 0.20, 'south': 0.10, 'west': 0.20},{'female': 0.70, 'male': 0.30})
{('east', 'female'): 0.35, ('west', 'female'): 0.13999999999999999, ('south', 'male'): 0.03, ('north', 'male'): 0.06, ('south', 'female'): 0.06999999999999999, ('north', 'female'): 0.13999999999999999, ('west', 'male'): 0.06, ('east', 'male'): 0.15}
但它提供了额外的灵活性:
three or more dictionaries, like:
>>> cartesian_dictionary({'a':2,'b':3},{'c':0.5,'d':1},{'e':1,'f':2})
{('b', 'c', 'e'): 1.5, ('a', 'c', 'f'): 2.0, ('b', 'd', 'f'): 6, ('a', 'c', 'e'): 1.0, ('b', 'd', 'e'): 3, ('a', 'd', 'f'): 4, ('b', 'c', 'f'): 3.0, ('a', 'd', 'e'): 2}
other way to "fold" values:
>>> cartesian_dictionary({'a':2,'b':3},{'c':0.5,'d':1},fold=operator.add)
{('a', 'd'): 3, ('b', 'd'): 4, ('b', 'c'): 3.5, ('a', 'c'): 2.5}