Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Say the we have the following two dictionaries in Python:
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4}
dict2 = {'c':2, 'd':1, 'b':2, 'a':1}
Now, I'm assuming that the values in dict1 are the correct values. How can I compare dict2 to dict1, such that if the value of the key in dict2 is similar to that in dict1 the program returns True, and if it is different, it returns False?
Thanks.
If by similar you mean equal, then you can just directly compare them:
def compare_dictionaries(correct_dictionary,dictionary_to_check):
for key,correct_value in correct_dictionary.items():
if dictionary_to_check[key] != correct_value:
return False
return True
The above will throw a KeyError exception if you are missing a key in the dictionary you need to check and does nothing to handle if the dictionary you are checking contains extra keys.
I am guessing that dict1 key: values are what everything is being compared to.
dict2 = {'c':2, 'd':1, 'b':2, 'a':1}
def compareDict(d2):
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4}
for key in d2:
if d2[key] == dict1[key]:
print("{} key has similar value of {}; It is True".format(key,
d2[key]))
else:
print("{} key does not have similar value as dict1 key, it has a
value of {}; It is False".format(key, d2[key]))
compareDict(dict2)
Firstly check the keys are same using xor operation and then check the value with corresponding key of the dictionary. Hope this will help.
dict1 = {'a':2, 'b':2, 'c':3, 'd': 4}
dict2 = {'c':2, 'd':1, 'b':2, 'a':1}
# XOR operator for for checking all key are same.
check_keys= set(dict1.keys()) ^ set(dict2.keys())
keys = set(dict2.keys())
check = False
# a=0 if all key are same.
a = len(check_keys)
# if all key are same than check the value with corresponding key
if not a:
check = True
for key in keys:
if dict1[key] == dict2[key]:
pass
else:
check = False
break
print(check)
Compare dictionaries by size, keys and value for each key by giving a boolean flag.
def compareDictionaries(source, target, compareValues):
## compare if they are same
if (source == target):
return True
## covers scenario where target has more keys than source
if (len(target) > len(source)):
print("target has more keys than source")
return False
## iterate over target keys to check if they exists in
## source and depending on compareValues flag compare key's
## values
for key, values in target.items():
if (key in source.keys()):
if (compareValues):
if(not (source[key] == target[key])):
print ("key(" + key + ") don't have same values!")
return False
else:
print ("key(" + key + ") not found in source!")
return False
return True
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4}
dict2 = {'c':5, 'd':4, 'b':2, 'a':1}
if (compareDictionaries(dict1, dict2, False)):
print("Pass")
else:
print("Fail")
First implementation
# Both dictionaries can have different keys
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4} # correct dict
dict2 = {'c':2, 'd':1, 'b':2, 'a':1} # test dict
if all(map(lambda x: dict2.get(x, "dict2") == dict1.get(x, "dict1"), dict2)):
print "same"
else:
print "different"
Test case #1 gives "same"
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4, 'e':5} # correct dict
dict2 = {'c':3, 'd':4, 'b':2, 'a':1} # test dict
Test case #2 gives "different"
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4 } # correct dict
dict2 = {'c':3, 'd':4, 'b':2, 'a':1, 'e':5} # test dict
Second implementation (different from first, see test results)
# Both dictionaries can have different keys
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4} # correct dict
dict2 = {'c':2, 'd':1, 'b':2, 'a':1} # test dict
if set(dict1.keys()) == set(dict2.keys()) and set(dict1.values()) == set(dict2.values()):
print "same"
else:
print "different"
Test case #1 gives "different"
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4, 'e':5} # correct dict
dict2 = {'c':3, 'd':4, 'b':2, 'a':1} # test dict
Test case #2 gives "different"
dict1 = {'a':1, 'b':2, 'c':3, 'd': 4 } # correct dict
dict2 = {'c':3, 'd':4, 'b':2, 'a':1, 'e':5} # test dict
Related
I have a dictionary and a list:
dictionary = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
remove = ['b', 'c', 'e']
I need to split "dictionary" into two dictionaries using "remove". The idea is to remove keys in "remove" from "dictionary" but instead of discarding them, I want to keep them in a new dictionary. The outcome I want is
old_dictionary = {'a':1, 'd':4, 'f':6}
new_dictionary = {'b':2, 'c':3, 'e':5}
Getting "new_dictionary" is fairly easy.
new_dictionary = {}
for key, value in dictionary.items():
if key in remove:
new_dictionary[key] = value
How do I find the difference between "dictionary" and "new_dictionary" to get "old_dictionary"? I guess I could loop again only with not in remove... but is there a nice trick for dictionaries similar to set difference?
One way could be to use dict.pop in loop. dict.pop method removes the key and returns its value. So in each iteration, we remove a key in remove from dictionary and add this key along with its value to new_dict. At the end of the iteration, dictionary will have all keys in remove removed from it.
new_dict = {k: dictionary.pop(k) for k in remove}
old_dict = dictionary.copy()
Output:
>>> new_dict
{'b': 2, 'c': 3, 'e': 5}
>>> old_dict
{'a': 1, 'd': 4, 'f': 6}
Just add else
new_dictionary = {}
old_dictionary = {}
for key, value in dictionary.items():
if key in remove:
new_dictionary[key] = value
else:
old_dictionary[key] = value
Use else: to put it in the other dictionary.
new_dictionary = {}
old_dictionary = {}
for key, value in dictionary.items():
if key in remove:
new_dictionary[key] = value
else:
old_dictionary[key] = value
The dict.keys() or dict.items() can be operated like a set with other iterable sequences:
>>> dictionary = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6}
>>> remove = list('bce')
>>> new_dict = {key: dictionary[key] for key in remove}
>>> new_dict
{'b': 2, 'c': 3, 'e': 5}
>>> dict(dictionary.items() - new_dict.items())
{'d': 4, 'f': 6, 'a': 1}
However, in terms of performance, this method is not as good as the answer with the highest score.
This question already has answers here:
Removing Duplicates From Dictionary
(11 answers)
remove duplicates values in a dictionary python
(1 answer)
Closed 2 years ago.
More a concept question than a direct coding one. But say I had a dictionary akin to this one.
Dict = {'A':1, 'B':3, 'C':3, 'D':4, 'E':1}
Dict2 = {}
And I wanted to take all instances were two keys had the same value, and put them in a different dictionary, what sort of process be the most efficient? I've tried measures like
for value in Dict.items()
for a in value:
if a != b:
continue
else:
Dict2.append(a)
continue
But to no luck.
You can do something like this:
Dict = {'A':1, 'B':3, 'C':3, 'D':4, 'E':1}
result = {}
for k, v in Dict.items():
result.setdefault(v, set()).add(k)
print("Original: ")
print(Dict)
print("------------")
print("Result: ")
print(result)
Original:
{'A': 1, 'B': 3, 'C': 3, 'D': 4, 'E': 1}
Result:
{1: {'A', 'E'}, 3: {'B', 'C'}, 4: {'D'}}
Old school, with regular loops. Could maybe be done with list or dict comprehensions, but this is easy and obvious:
dict = {'A':1, 'B':3, 'C':3, 'D':4, 'E':1}
# Make a reverse dictionary that maps values to lists of keys
# that have that value in the original dict
reverse_dict = {}
for k, v in dict.items():
reverse_dict.setdefault(v, list()).append(k)
# Show the reverse dict
# print(reverse_dict)
# Move entries for keys that had duplicates from the original
# dict to a new dict
dups_dict = {}
for k, vs in reverse_dict.items():
if len(vs) > 1: # if there was more than one key with this value
for v in vs: # for each of those keys
dups_dict[v] = k # copy it to the new dict
del dict[v] # and remove it from the original dict
# Show the original dict and the new one
print(dict)
print(dups_dict)
Result:
{'D': 4}
{'A': 1, 'E': 1, 'B': 3, 'C': 3}
I would like to get a new dictionary with keys only if both dictionaries have those keys in them, and then get the values of the second one.
# example:
Dict1 = {'A':3, 'B':5, 'C':2, 'D':5}
Dict2 = {'B':3, 'C':1, 'K':5}
# result--> {'B':3, 'C':1}
As a dictionary comprehension:
>>> {k:v for k, v in Dict2.items() if k in Dict1}
{'B': 3, 'C': 1}
Or use filter:
>>> dict(filter(lambda x: x[0] in Dict1, Dict2.items()))
{'B': 3, 'C': 1}
>>>
Just another solution, doesn't use comprehension. This function loops through the keys k in Dict1 and tries to add Dict2[k] to a new dict which is returned at the end. I think the try-except approach is "pythonic".
def shared_keys(a, b):
"""
returns dict of all KVs in b which are also in a
"""
shared = {}
for k in a.keys():
try:
shared[k] = b[k]
except:
pass
return shared
Dict1 = {'A':3, 'B':5, 'C':2, 'D':5}
Dict2 = {'B':3, 'C':1, 'K':5}
print(shared_keys(Dict1, Dict2))
# >>> {'B': 3, 'C': 1}
I have two nested dictionary data. I want to merge them to create one dictionary in python.
Dictionary data :
dict1 = {'employee':{'dev1': 'Roy'}}
dict2 = {'employee':{'dev2': 'Biswas'}}
Now I trying to create a dictionary like bellow from them.Required Output
dict_output = {'employee':{
'dev1': 'Roy',
'dev2': 'Biswas'
}
}
my try:
import json
dict1 = {'employee':{'dev1': 'Roy'}}
dict2 = {'employee':{'dev2': 'Biswas'}}
dict1.update(dict2)
print(json.dumps(dict1, indent=2))
Output:
{
"employee": {
"dev2": "Biswas"
}
}
I am unable to merge both the dictionary.Need help to merge them
This code is to support slightly different meaning of "merge". Let's say we have a nested dictionary:
dict1 = {'employee':{'devs':{'python':{'dev1':'Roy'}}}}
dict2 = {'employee':{'devs':{'cpp':{'dev1':'Biswas'}}}}
In this case the simple loop solution returns:
{'employee': {'devs': {'cpp': {'dev1': 'Biswas'}}}}
While the "intuitive" answer should be:
{'employee': {'devs': {'python': {'dev1': 'Roy'}, 'cpp': {'dev1': 'Biswas'}}}}
This is just a simple example, the real example may be much more complex.
Below is my attempt for such a nested dictionary. It works for nested data using recursion. And it also has some restrictions. For example if dict1 and dict2 have the same value which is not dictionary, dict2 has priority. On the other hand if dict1 contains dictionary and dict2 contains value with the same key, the priority is upon dict1 and dict2 is ignored. Other restrictions will require code changes.
def merge_dict(dict1, dict2):
for key, val in dict1.items():
if type(val) == dict:
if key in dict2 and type(dict2[key] == dict):
merge_dict(dict1[key], dict2[key])
else:
if key in dict2:
dict1[key] = dict2[key]
for key, val in dict2.items():
if not key in dict1:
dict1[key] = val
return dict1
dict1 = merge_dict(dict1, dict2)
You can just update the inner dictionary.
>>> dict1 = {'employee':{'dev1': 'Roy'}}
>>> dict2 = {'employee':{'dev2': 'Biswas'}}
>>>
>>> for key in dict1:
... if key in dict2:
... dict1[key].update(dict2[key])
...
>>> dict1
{'employee': {'dev2': 'Biswas', 'dev1': 'Roy'}}
Here's a solution that should work even if both dictionaries have different keys, and you want to keep them all.
from collections import defaultdict
dict1 = {'employee': {'dev1': 'Roy'}, 'aKeyNotInDict2': {}}
dict2 = {'employee': {'dev2': 'Biswas'}, 'aKeyNotInDict1': {}}
merged_dict = defaultdict(dict)
merged_dict.update(dict1)
for key, nested_dict in dict2.items():
merged_dict[key].update(nested_dict)
print(dict(merged_dict))
Output:
{
'employee': {'dev2': 'Biswas', 'dev1': 'Roy'},
'aKeyNotInDict2': {},
'aKeyNotInDict1': {}
}
#use a dict comprehension. Adding {} in get() is to set a default return value if the key doesn't exist in dict1
{k:dict(dict1.get(k,{}).items() + v.items()) for k,v in dict2.items()}
Out[689]: {'employee': {'dev1': 'Roy', 'dev2': 'Biswas'}}
#Alternatively, a less readable way to merge the dicts using the dict constructor.
{k:dict(dict1.get(k,{}), **v) for k,v in dict2.items()}
Out[690]: {'employee': {'dev1': 'Roy', 'dev2': 'Biswas'}}
Maybe you can try naapc package as follows:
>>> from naapc import NDict
>>> dict1 = NDict({'employee':{'dev1': 'Roy'}})
>>> dict2 = {'employee':{'dev2': 'Biswas'}}
>>> dict1.update(dict2)
>>> print(dict1)
{
"employee": {
"dev1": "Roy",
"dev2": "Biswas"
}
}
In case you want a normal dict:
normal_dict = deepcopy(dict1.raw_dict)
To install:
pip install naapc
doc in: https://github.com/eiphy/naapc
def m3(a,b):
if not isinstance(a,dict) and not isinstance(b,dict):return b
for k in b:
if k in a :
a[k] = m3(a[k], b[k])
else: a[k] = b[k]
return a
d1 = {1:{"a":"A"}, 2:{"b":"B"}}
d2 = {2:{"c":"C"}, 3:{"d":"D"}}
d3 = {1:{"a":{1}}, 2:{"b":{2}}}
d4 = {2:{"c":{222}}, 3:{"d":{3}}}
d5 = {'employee':{'dev1': 'Roy'}}
d6 = {'employee':{'dev2': 'Biswas'}}
print(m3(d1,d2))
print(m3(d3,d4))
print(m3(d5,d6))
"""
Output :
{1: {'a': 'A'}, 2: {'b': 'B', 'c': 'C'}, 3: {'d': 'D'}}
{1: {'a': {1}}, 2: {'b': {2}, 'c': {222}}, 3: {'d': {3}}}
{'employee': {'dev1': 'Roy', 'dev2': 'Biswas'}}
"""
Explanation:
If a and b are not dictionaries, return b
For each key in b, if the key is in a, then merge the values of the key in a and b.
If the key is not in a, then add the key and value to a.
Return a.
But yes, The best and shortest way is this:
def m4(a,b):
for k in a:
a.get(k).update(b.get(k, {}))
return a
Explanation:
The function m4 takes two dictionaries as input.
The function iterates through the first dictionary
and updates the values of the first dictionary with
the values of the second dictionary.
The function returns the first dictionary.
[key1 == key2 and dict1.get(key1).update(dict2.get(key2))
for key1, key2 in zip(dict1, dict2)]
print dict1
I have a list of dictionaries (with some data fetched from an API) assume:
alist = [{'a':1, 'b':2, 'c':3}, {'a':1, 'b':2, 'c':35}, {'a':1, 'b':2, 'c':87}..]
There are multiple dictionaries which are repeated in alist. But only one of key has a different values out of repeated dictionaries.So, the query is:
What's the easiest way to combine those dictionaries by keeping separate values in a list?
like:
alist = [{'a':1, 'b':2, 'c':[3, 35, 87]}...]
Update - I have a list which specifies me the repeated keys like:
repeated_keys = ['c',...]
Use defaultdict (it is faster ) and generate dictionary from it- you can also easily convert that dictionary into list.You can modify j in i.keys() to filter keys.
from collections import defaultdict as df
d=df(list)
alist = [{'a':1, 'b':2, 'c':3}, {'a':1, 'b':2, 'c':35}, {'a':1, 'b':2, 'c':87}]
for i in alist:
for j in i.keys():
d[j].append(i[j])
print dict(d.items())
Output-
{'a': [1, 1, 1], 'c': [3, 35, 87], 'b': [2, 2, 2]}
If you want to get rid of repeated element from that use dict-comprehension and set-
>>>{k:list(set(v)) for k,v in d.items()}
>>>{'a': [1], 'c': [35, 3, 87], 'b': [2]}
You could use a list comprehension:
result = [alist[0].copy()]
result[0]['c'] = [d['c'] for d in alist]
Note that there is little point in making this a list again; you combined everything into one dictionary, after all:
result = dict(alist[0], c=[d['c'] for d in alist])
If you have multiple repeated keys, you have two options:
Loop and get each key out:
result = alist[0].copy()
for key in repeated:
result[key] = [d[key] for d in alist]
Make all keys lists, that way you don't have to keep consulting your list of repeated keys:
result = {}
for key in alist[0]:
result[key] = [d[key] for d in alist]
The latter option is alternatively implemented by iterating over alist just once:
result = {}
for d in alist:
for key, value in d.items():
result.setdefault(key, []).append(value)
from collections import defaultdict
con_dict = defaultdict(list)
alist = [{'a':1, 'b':2, 'c':3}, {'a':1, 'b':2, 'c':35}, {'a':1, 'b':2, 'c':87}]
for curr_dict in alist:
for k, v in curr_dict.iteritems():
con_dict[k].append(v)
con_dict = dict(con_dict)
We create a default dict of type list and then iterate over the items and append them in the right key.
It is possible to get your result.You have to test if you want to create a list if items has different values or keep it as is.
repeated_keys is used to store repeated keys and count how many times they are repeated.
alist = [{'a':1, 'b':2, 'c':3}, {'a':1, 'b':2, 'c':35}, {'a':1, 'b':2, 'c':87}]
z = {}
repeated_keys = {}
for dict in alist:
for key in dict:
if z.has_key(key):
if isinstance(z[key], list):
if not dict[key] in z[key]:
repeated_keys[key] +=1
z[key].append(dict[key])
else:
if z[key] != dict[key]:
repeated_keys[key] = 1
z[key] = [z[key], dict[key]]
else:
z[key] = dict[key]
print 'dict: ',z
print 'Repeated keys: ', repeated_keys
output:
dict: {'a': [1, 3], 'c': [3, 35, 87], 'b': 2}
Repeated keys: {'c'}
if:
alist = [{'a':1, 'b':2, 'c':3}, {'a':1, 'b':2, 'c':35}, {'a':1, 'b':2, 'c':87}, {'a':3,'b':2}]
output should be:
dict: {'a': [1, 3], 'c': [3, 35, 87], 'b': 2}
Repeated keys: {'a': 1, 'c': 2}