简体   繁体   English

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

[英]Subtract values from list of dictionaries from another list of dictionaries

I have two lists of dictionaries. 我有两个词典列表。

foo = [{'Tom': 8.2}, {'Bob': 16.7}, {'Mike': 11.6}]
bar = [{'Tom': 4.2}, {'Bob': 6.7}, {'Mike': 10.2}]

The subtraction of a and b should be updated in foo: 应该在foo中更新a和b的减法:

foo = [{'Tom': 4.0}, {'Bob': 10.0}, {'Mike': 1.4}]

Now I tried this with two loops and the zip -function: 现在我尝试了两个循环和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)

I get a TypeError: 'float' object is not iterable . 我得到一个TypeError: 'float' object is not iterable Where's my mistake? 哪里是我的错?

You were very close. 你非常接近。 The issue was the list comprehension you had in your dictionary comprehension. 问题是你在词典理解中的列表理解。 mydict[k], mydictcorr[k] were both returning floats, but you were trying to iterate over them [xy for x, y in mydict[k], mydictcorr[k]] . mydict[k], mydictcorr[k]都返回浮点数,但是你试图迭代它们[xy for x, y in mydict[k], mydictcorr[k]]

This will work for you: 这对你有用:

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

Or as a much less readable one-liner (because I wanted to see if I could): 或者作为一个不太可读的单行(因为我想看看我是否可以):

def sub(base, subtract):
    return [{k: v - sub_dict.get(k, 0) for k, v in base_dict.items()} for base_dict, sub_dict in zip(base, subtract)]

Having said that, you may still see some weird results when you subtract floats. 话虽如此,当您减去浮点数时,您仍可能会看到一些奇怪的结果。 Eg, {'Tom': 3.999999999999999} . 例如, {'Tom': 3.999999999999999} You may want to wrap v - sub_dict.get(k, 0) in a call to round. 您可能希望在对round的调用中包装v - sub_dict.get(k, 0)

You can build dictionaries from foo and bar and use list comprehension: 您可以从foobar构建字典并使用列表理解:

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

Output: 输出:

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

If you want the dicts in foo updated you can do it directly as lists and dicts are both immutable: 如果你想要更新foo的dicts你可以直接做,因为列表和dicts都是不可变的:

def sub(a, b):
    for d1, d2 in zip(a, b):
        for k, v in d2.items():
            d1[k] -= v

Any changes will be reflected in your list which just holds references to your dicst: 任何更改都将反映在您的列表中,该列表仅包含对您的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}]

As you can see you also need to be aware of floating-point-arithmetic-issues-and-limitations 如您所见,您还需要了解浮点运算问题和限制

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM