Python 从另一个字典列表中减去字典列表中的值

Python 从另一个字典列表中减去字典列表中的值,python,python-2.7,loops,dictionary,Python,Python 2.7,Loops,Dictionary,我有两本字典的目录 foo = [{'Tom': 8.2}, {'Bob': 16.7}, {'Mike': 11.6}] bar = [{'Tom': 4.2}, {'Bob': 6.7}, {'Mike': 10.2}] a和b的减法应在foo中更新: foo = [{'Tom': 4.0}, {'Bob': 10.0}, {'Mike': 1.4}] 现在我尝试了两个循环和zip-函数: def sub(a,b): for mydict,mydictcorr in

我有两本字典的目录

foo = [{'Tom': 8.2}, {'Bob': 16.7}, {'Mike': 11.6}]
bar = [{'Tom': 4.2}, {'Bob': 6.7}, {'Mike': 10.2}]
a和b的减法应在foo中更新:

foo = [{'Tom': 4.0}, {'Bob': 10.0}, {'Mike': 1.4}]
现在我尝试了两个循环和
zip
-函数:

def sub(a,b):       
    for mydict,mydictcorr in zip(a,b):
        {k:[x-y for x, y in mydict[k], mydictcorr[k]] for k in mydict}
    return mydict
print sub(foo,bar)

我得到一个
类型错误:“float”对象不可编辑。我的错误在哪里?

你很接近。问题是你在字典理解中的列表理解
mydict[k],mydictcorr[k]
都返回浮点,但您试图在它们上面迭代
[x-y代表x,y代表mydict[k],mydictcorr[k]]

这将对您有用:

def sub(base, subtract):
    corrected = []
    for base_dict, sub_dict in zip(base, subtract):
        corrected.append({k: v - sub_dict.get(k, 0) for k, v in base_dict.items()})
    return corrected
或者作为可读性差得多的一行(因为我想看看是否可以):


尽管如此,当你减去浮点数时,你可能仍然会看到一些奇怪的结果。例如,
{'Tom':3.999999999999}
。您可能希望在调用round时包装
v-sub_dict.get(k,0)

您可以从
foo
bar
构建词典,并使用列表理解:

a = dict([next(x.iteritems()) for x in foo])    
b = dict([next(x.iteritems()) for x in bar])

sub_dict = dict([(key, round(a[key] - b.get(key, 0), 1)) for key in a])
输出:

{'Bob': 10.0, 'Mike': 1.4, 'Tom': 4.0}

如果您想更新
foo
中的dict,可以直接更新,因为列表和dict都是不可变的:

def sub(a, b):
    for d1, d2 in zip(a, b):
        for k, v in d2.items():
            d1[k] -= v
任何更改都将反映在您的列表中,该列表仅包含对您的dicst的引用:

In [2]: foo
Out[2]: [{'Tom': 8.2}, {'Bob': 16.7}, {'Mike': 11.6}]

In [3]: sub(foo, bar)

In [4]: foo
Out[4]: [{'Tom': 3.999999999999999}, {'Bob': 10.0}, {'Mike': 1.4000000000000004}]

正如您所见,您还需要意识到您的数据结构是错误的
foo
bar
可能不应该是字典列表。或者至少字典不应该有不同的键。你代表什么?你需要如何处理这些数据?@GeoEki很高兴我能帮上忙!
In [2]: foo
Out[2]: [{'Tom': 8.2}, {'Bob': 16.7}, {'Mike': 11.6}]

In [3]: sub(foo, bar)

In [4]: foo
Out[4]: [{'Tom': 3.999999999999999}, {'Bob': 10.0}, {'Mike': 1.4000000000000004}]