Subtract values ​​from the dictionary list from another dictionary list

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

Subtraction of a and b should be updated in foo:

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

Now I tried this with two loops and a zip function:

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

I get TypeError: 'float' object is not iterable . Where is my mistake?

+5
source share
3 answers

You were very close. The problem was understanding the list that you had in understanding the dictionary. mydict[k], mydictcorr[k] both returned floats, but you tried to [xy for x, y in mydict[k], mydictcorr[k]] over them [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 single line (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 can still see some strange results when you subtract the floats. For example, {'Tom': 3.999999999999999} . You can wrap v - sub_dict.get(k, 0) when calling round.

+3
source

You can create dictionaries from foo and bar and use list comprehension:

 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} 
0
source

If you want to update dicts in foo , you can do it directly, since lists and dicts are immutable:

 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 simply contains links to your 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 know floating-point-arithmetic-issues-and-limitations

0
source

Source: https://habr.com/ru/post/1234287/


All Articles