Python compare matching keys and print values, keys - python

I know there are somewhat similar questions to this, but none have answered specifically what I'm trying to do and I haven't had any luck with it. I have two dictionaries and I want to print out the key and values if the values of it are larger than the or not in dictionary two.
So for instance:
dict1 = {'T': 5, 'X': 10, 'Y': 15, 'Z': 25}
dict2 = {'U': 10, 'X': 11, 'Y': 15, 'Z': 15}
How do I get it to only print 'T': 5, 'Z': 25?

for key in dict1:
if key not in dict2 or dict1[key] > dict2[key]:
print("'%s': %d" % (key, dict1[key]))

Related

Why is this dictionary turning into a tuple?

I have a complex dictionary:
l = {10: [{'a':1, 'T':'y'}, {'a':2, 'T':'n'}], 20: [{'a':3,'T':'n'}]}
When I'm trying to iterate over the dictionary I'm not getting a dictionary with a list for values that are a dictionary I'm getting a tuple like so:
for m in l.items():
print(m)
(10, [{'a': 1, 'T': 'y'}, {'a': 2, 'T': 'n'}])
(20, [{'a': 3, 'T': 'n'}])
But when I just print l I get my original dictionary:
In [7]: l
Out[7]: {10: [{'a': 1, 'T': 'y'}, {'a': 2, 'T': 'n'}], 20: [{'a': 3, 'T': 'n'}]}
How do I iterate over the dictionary? I still need the keys and to process each dictionary in the value list.
There are two questions here. First, you ask why this is turned into a "tuple" - the answer to that question is because that is what the .items() method on dictionaries returns - a tuple of each key/value pair.
Knowing this, you can then decide how to use this information. You can choose to expand the tuple into the two parts during iteration
for k, v in l.items():
# Now k has the value of the key and v is the value
# So you can either use the value directly
print(v[0]);
# or access using the key
value = l[k];
print(value[0]);
# Both yield the same value
With a dictionary you can add another variable while iterating over it.
for key, value in l.items():
print(key,value)
I often rely on pprint when processing a nested object to know at a glance what structure that I am dealing with.
from pprint import pprint
l = {10: [{'a':1, 'T':'y'}, {'a':2, 'T':'n'}], 20: [{'a':3,'T':'n'}]}
pprint(l, indent=4, width=40)
Output:
{ 10: [ {'T': 'y', 'a': 1},
{'T': 'n', 'a': 2}],
20: [{'T': 'n', 'a': 3}]}
Others have already answered with implementations.
Thanks for all the help. I did discuss figure out how to process this. Here is the implementation I came up with:
for m in l.items():
k,v = m
print(f"key: {k}, val: {v}")
for n in v:
print(f"key: {n['a']}, val: {n['T']}")
Thanks for everyones help!

comparing four dictionaries that their keys are same but each has different values in python

i have four dictionaries like below and i want to print them in order of their first values and if they were equal then print them in order of their second values but i cant figure a way. i've tried to put all of the values of 'p' in a list and sort the list but again i couldn't find a way to call which value is for which dictionary
a = {'p':10, 'w':3}
b = {'p':2, 'w':0}
c = {'p':3, 'w':0}
d = {'p':3, 'w':1}
the output should be this:
{'p':10, 'w':3}
{'p':3, 'w':1}
{'p':3, 'w':0}
{'p':2, 'w':0}
Use the key argument to sorted to get the custom sort order.
a = {'p':10, 'w':3}
b = {'p':2, 'w':0}
c = {'p':3, 'w':0}
d = {'p':3, 'w':1}
dicts = [a,b,c,d]
print(sorted(dicts, reverse=True, key=lambda d: (d['p'], d['w'])))
For each dict, the key is the tuple of the p value and the w value - which gives the required sort order
Output:
[{'p': 10, 'w': 3}, {'p': 3, 'w': 1}, {'p': 3, 'w': 0}, {'p': 2, 'w': 0}]
Use the key argument of the sort function. Here is a solution to the problem (note that reverse makes sure the largest appears first).
dict_list = [a,b,c,d]
dict_list.sort(reverse=True, key=lambda x: (x['p'], x['w']))
print(dict_list)
[{'p': 10, 'w': 3}, {'p': 3, 'w': 1}, {'p': 3, 'w': 0}, {'p': 2, 'w': 0}]

How to merge with two objects into a tuple with the two elements?

I'm new to python and I was trying to merge two objects into a tuple with the two elements?
I've tried like merging lists, summing them and so on, nothing worked as I wanted. The code I'm providing doesn`t works also.
def merge(dict1,dict2):
for key in dict2:
if key in dict1:
dict2[key]=dict2[key]+dict1[key]
else:
pass
return dict2
The input is this:
a = {'x': [1,2,3], 'y': 1, 'z': set([1,2,3]), 'w': 'qweqwe', 't': {'a': [1, 2]}, 'm': [1]}
And this:
b = {'x': [4,5,6], 'y': 4, 'z': set([4,2,3]), 'w': 'asdf', 't': {'a': [3, 2]}, 'm': "wer"}
And I want the output to be this:
{'x': [1,2,3,4,5,6], 'y': 5, 'z': set([1,2,3,4]), 'w': 'qweqweasdf', 't': {'a': [1, 2, 3, 2]}, 'm': ([1], "wer")}
With ^this being a single tuple.
Given there are so many types, a lot of type checking is required, but this simple recursion should work.
Also, this assumes the keys in a and b are the same, as they are in the example.
def merge(a,b,new_dict):
for key in a.keys():
if type(a[key]) != type(b[key]):
new_dict[key] = (a[key],b[key])
elif type(a[key]) == dict:
new_dict[key] = merge(a[key],b[key],{})
elif type(a[key]) == set:
new_dict[key] = a[key]|b[key]
else:
new_dict[key] = a[key] + b[key]
return new_dict
c = merge(a,b,{})

Merging dict of dicts and sum values

I'm looking for a way to merge multiple dicts with each other, which contain nested dicts too. The number of nested dicts is not static but dynamic.
At the end the Final dict should contain all the dicts of dicts and the sum of their values:
COUNTRY1 = {'a': {'X': 10, 'Y': 18, 'Z': 17}, 'b': {'AA':{'AAx':45,'AAy':22},'BB':{'BBx':45,'BBy':22}}, 'c': 100}
COUNTRY2 = {'a': {'U': 12, 'V': 34, 'W': 23}, 'b': {'AA':{'AAz':23,'AAa':26},'BB':{'BBz':11,'BBa':15}}, 'c': 115}
COUNTRY3 = {'a': {'Y': 15, 'Z': 14, 'X': 12}, 'b': {'AA':{'AAx':45,'AAz':22},'BB':{'BBy':45,'BBz':22}}, 'c': 232}
# After merging the dictionaries the result should look like:
ALL
>>> {'a': {'X': 22, 'Y': 33, 'Z': 31, 'U': 12, 'V': 34, 'W': 23}, 'b': {'AA':{'AAx':90,'AAy':22,'AAz':45,'AAa':26},'BB':{'BBx':45,'BBy':67, 'BBz':33,'BBa':15}}, 'c': 447}
I tried the following code which allows nested dicts to a max of 3 nested dicts. Unfortunately the code doesn't do what I expected. Thereby it doesn't look very clean, I feel like this could be done with a recursive function, however I can't find a way to do it.
COUNTRIES = ['COUNTRY1','COUNTRY2', 'COUNTRY3']
ALL = {}
for COUNTRY_CODE in COUNTRIES:
COUNTRY = pickle.load(open(COUNTRY_CODE+".p", "rb"))
keys = COUNTRY.keys()
for key in keys:
try:
keys2 = COUNTRY[key].keys()
print(key, keys2)
for key2 in keys2:
try:
keys3 = COUNTRY[key][key2].keys()
print(key2, keys3)
for key3 in keys3:
try:
keys4 = COUNTRY[key][key2][key3].keys()
print(key3, keys4)
except:
print(key3, "NO KEY3")
if not key3 in ALL[key][key2]:
ALL[key][key2][key3] = COUNTRY[key][key2][key3]
else:
ALL[key][key2][key3] =+ COUNTRY[key][key2][key3]
except:
print(key2, "NO KEY2")
if not key2 in ALL[key]:
ALL[key][key2] = COUNTRY[key][key2]
else:
ALL[key][key2] =+ COUNTRY[key][key2]
except:
print(key, "NO KEY")
if not key in ALL:
ALL[key] = COUNTRY[key]
else:
ALL[key] =+ COUNTRY[key]
print(ALL)
The issue is that you need to determine what to do with a dictionary key based on the type of the value. The basic idea is:
Input is a pair of dictionaries, output is the sum dictionary
Step along both input dictionaries
If a value is a dictionary, recurse
If a value is a number, add it to the other number
This is fairly easy to implement with a comprehension:
def add_dicts(d1, d2):
def sum(v1, v2):
if v2 is None:
return v1
try:
return v1 + v2
except TypeError:
return add_dicts(v1, v2)
result = d2.copy()
result.update({k: sum(v, d2.get(k)) for k, v in d1.items()})
return result
The copy ensures that any keys in d2 that are not also in d1 are simply copied over.
You can now sum as follows:
ALL = add_dicts(add_dicts(COUNTRY1, COUNTRY2), COUNTRY3)
More generally, you can use functools.reduce to do this for an indefinite number of dictionaries:
dicts = [COUNTRY1, COUNTRY2, COUNTRY3]
ALL = reduce(add_dicts, dicts)
Make two functions like below:
def cal_sum(lst):
final_dict = dict()
for l in lst:
sum(final_dict,l)
return final_dict
def sum(final_dict,iter_dict):
for k, v in iter_dict.items():
if isinstance(v, dict):
sum(final_dict.setdefault(k, dict()), v)
elif isinstance(v, int):
final_dict[k] = final_dict.get(k, 0) + v
Calling the above code as follows produces the desired output:
>>> print(cal_sum([COUNTRY1, COUNTRY2, COUNTRY3]))
{'a': {'U': 12, 'W': 23, 'V': 34, 'Y': 33, 'X': 22, 'Z': 31}, 'c': 447, 'b': {'AA': {'AAa': 26, 'AAy': 22, 'AAx': 90, 'AAz': 45}, 'BB': {'BBa': 15, 'BBz': 33, 'BBy': 67, 'BBx': 45}}}

Combining Two Dictionaries by Like Keys

Let's say I have two dictionaries like so:
first_dict = {'1': 3, '2': 4, '3':8, '9': 20}
second_dict = {'3': 40, '9': 28, '100': 3}
Now here's the idea: I want to get all the keys that are the same, and make the entries for those keys into a dictionary of each value.
For example:
combined_dict = {'3': {'first_dict': 8, 'second_dict': 40}, '9': {'first_dict': 20, 'second_dict':28}}
What would be the best way to accomplish this for larger dictionaries?
Use dictionary view objects:
combined_dict = {key: {'first_dict': first_dict[key], 'second_dict': second_dict[key]}
for key in first_dict.viewkeys() & second_dict}
The expression first_dict.viewkeys() & second_dict uses a set intersection to list just the keys that both dictionaries have in common. The dict.viewkeys() gives us a view into the dictionary that acts like a set without creating a whole new set object.
This makes the above expression more efficient than creating two sets and intersecting those, especially when dealing with large dictionaries.
common_keys = set(first_dict.keys()) & set(second_dict.keys())
combined_dict = { key: {'first_dict': first_dict[key],
'second_dict': second_dict[key] } for key in common_keys
}
This works with arbitrary number of dicts:
def combine(**kwargs):
return { k: { d: kwargs[d][k] for d in kwargs
} for k in set.intersection(*map(set, kwargs.values()))
}
For example:
print combine(
one={'1': 3, '2': 4, '3':8, '9': 20},
two={'3': 40, '9': 28, '100': 3},
three={'3':14, '9':42})
# {'9': {'one': 20, 'three': 42, 'two': 28}, '3': {'one': 8, 'three': 14, 'two': 40}}

Categories

Resources