2016-08-23 122 views
3

我想要减去dict1 - dict2。不要紧,如果结果是狗负数,我只是有兴趣学习的概念:)减去两个字典的值

owner = ['Bob', 'Sarah', 'Ann'] 

dict1 = {'Bob': {'shepherd': [4,6,3],'collie': [23, 3, 45], 'poodle':[2,0,6]}, {'Sarah': {'shepherd': [1,2,3],'collie': [3, 31, 4], 'poodle': [21,5,6]},{'Ann': {'shepherd': [4,6,3],'collie': [23, 3, 45], 'poodle': [2,10,8]}} 


dict2 = {'Bob': {'shepherd': 10,'collie': 15,'poodle': 34},'Sarah': {'shepherd': 3,'collie': 25,'poodle': 4},'Ann': {'shepherd': 2,'collie': 1,'poodle': 0}} 

我想:

wanted = dict1 = {'Bob': {'shepherd': [-6,-4,-7],'collie': [8, -12, 30], 'poodle':[-32,-34,-28]}, {'Sarah': {'shepherd': [-2,-1,0],'collie': [-22, 6, -21], 'poodle': [17,1,2]},{'Ann': {'shepherd': [2,4,1],'collie': [22, 2, 44], 'poodle': [2,10,8]}} 

我还是新的字典所以这里是我一直在尝试,但得到NoneType错误。我假设这是因为dict1比dict2更多的值,但我找不到执行上述计算的方法。

wanted = {} 

for i in owner: 
    wanted.update({i: dict1.get(i) - dict2.get(i)}) 

回答

6

您可以使用嵌套字典理解。我修改了一下你的字典,因为它的语法不正确(还有一些额外的花括号)。没有必要使用所有者数组,因为我们只能使用字典中的键。

dict1 = { 
    'Bob': { 
     'shepherd': [4, 6, 3], 
     'collie': [23, 3, 45], 
     'poodle': [2, 0, 6], 
    }, 
    'Sarah': { 
     'shepherd': [1, 2, 3], 
     'collie': [3, 31, 4], 
     'poodle': [21, 5, 6], 
    }, 
    'Ann': { 
     'shepherd': [4, 6, 3], 
     'collie': [23, 3, 45], 
     'poodle': [2, 10, 8], 
    } 
} 
dict2 = { 
    'Bob': {'shepherd': 10, 'collie': 15, 'poodle': 34}, 
    'Sarah': {'shepherd': 3, 'collie': 25, 'poodle': 4}, 
    'Ann': {'shepherd': 2, 'collie': 1, 'poodle': 0}, 
} 
wanted = { 
    owner: { 
     dog: [num - dict2[owner][dog] for num in num_list] 
     for dog, num_list in dog_dict.iteritems() 
    } for owner, dog_dict in dict1.iteritems() 
} 
print wanted 

输出:

{ 
    'Sarah': { 
     'shepherd': [-2, -1, 0], 
     'collie': [-22, 6, -21], 
     'poodle': [17, 1, 2] 
    }, 
    'Bob': { 
     'shepherd': [-6, -4, -7], 
     'collie': [8, -12, 30], 
     'poodle': [-32, -34, -28] 
    }, 
    'Ann': { 
     'shepherd': [2, 4, 1], 
     'collie': [22, 2, 44], 
     'poodle': [2, 10, 8] 
    } 
} 

这是假设dict2具有所有相同的密钥dict1的。如果情况并非如此,则需要设置一些默认值以避免KeyError

编辑:下面简要说明如何为不熟悉它的人解释字典理解。如果你更熟悉列表推导,字典理解非常相似,只有你创建一个字典而不是列表。所以,{i: str(i) for i in xrange(10)}会给你一个{0: '0', 1: '1', ..., 9: '9'}的字典。

现在我们可以将其应用于解决方案。此代码:

wanted = { 
    owner: { 
     dog: [num - dict2[owner][dog] for num in num_list] 
     for dog, num_list in dog_dict.iteritems() 
    } for owner, dog_dict in dict1.iteritems() 
} 

等同于:

wanted = {} 
for owner, dog_dict in dict1.iteritems(): 
    wanted[owner] = {} 
    for dog, num_list in dog_dict.iteritems(): 
     wanted[owner][dog] = [num - dict2[owner][dog] for num in num_list] 
+0

能否请您解释一下嵌套字典理解的想法?至少如何迭代dict1。这个问题非常有趣,但答案很复杂。 – Monica

+1

@莫妮卡:我不同意答案是错综复杂的:它是最直接,最蟒蛇式的做法。起初可能会让你困惑的是你有3个嵌套列表/字典解释。为了理解它,尝试从内向外按照1的顺序将它们分解。 – Julien

+1

@Monica - 我添加了一个脚注,试图解释一下嵌套的字典解释。关键是要贯穿每一层。正如Julien指出的那样,这是一个很棒的Pythonic构造,值得学习:) – Karin