I do not understand how to switch keys while using two dictionaries - python

"""
Given two dictionaries, find the keys they have in common,
and return a new dictionary that maps the corresponding values.
Example:
dict1 == {"a":"alpha", "d":"delta", "x":"xi"}
dict2 == {"b":"bet", "d":"dalet", "l":"lamed", "a":"alef"}
should return:
{"alpha":"alef", "delta":"dalet", "beta":"bet"}
"""
dict1 == {"a":"alpha", "d":"delta", "x":"xi"}
dict2 == {"b":"bet", "d":"dalet", "l":"lamed", "a":"alef"}
new_dict = {}
for key, value in dict1.items():
if value in new_dict:
new_dict[value].append(key)
else:
new_dict[value]=[key]
This is what I have, all I have to do is make it so that the output is what is the same as {"alpha":"alef", "delta":"dalet", "beta":"bet"} which is just switching the keys.

According to your question if two dictionaries are like this:
dict1= {"a":"alpha", "d":"delta", "x":"xi"}
dict2 == {"b":"bet", "d":"dalet", "l":"lamed", "a":"alef"}
comm_keys = set(dict1.keys()).intersection(dict2.keys())
required_dict = {dict1[key]: dict2[key] for key in comm_keys}
# Expected output : {'delta': 'dalet', 'alpha': 'alef'}

One more way which you can do this is to use dictionary comprehension
dict1 = {"a": "alpha", "d": "delta", "x": "xi"}
dict2 = {"b": "bet", "d": "dalet", "l": "lamed", "a": "alef"}
output = {dict1[x]: dict2[x] for x in dict1 if x in dict2}
{'alpha': 'alef', 'delta': 'dalet'}

Related

How do I change a key's value to that of another key's value if the value is the name of another key?

To explain what I mean, I'm adding keys and values to a dictionary but if a key in the dictionary has a value that's the name of another key, I want that key to be assigned the other key's value. For example, if I have dict1 = {"a": 100, "b": 200, "c": "a"}
is it possible to change the value of c to 100 (which is a's value)? So instead it would be
dict1 = {"a": 100, "b": 200, "c": 100} The code I have right now is obviously wrong and giving me an error but I was trying to type out what I thought would work
for x, y in dict1.items():
if dict1[x] == dict1[x]:
dict1[x] = dict1[y]
print(x, y)
You can use:
my_dict = {"a": 100, "b": 200, "c": "a"}
for k, v in my_dict.items():
if v in my_dict:
my_dict[k] = my_dict[v]
You can alternatively use a dict comprehension:
result = {
k: my_dict[v] if v in my_dict else v
for k, v in my_dict.items()
}
Output:
{'a': 100, 'b': 200, 'c': 100}

Python Merge dictionaries of same length but different keys

I have two dictionaries of same length but not the same keys like below
dict1 = {"integervalue": None, "floatingValue": None, "stringValue": None}
dict2 = {"0": 10, "1": 0.1020, "2": "XXX"}
I need to update the values of second dictionary to first (dictionaries of same length) and using zip to achieve like below
for (k, v) in zip(dict1, dict2):
dict1[k] = dict2[v]
this does the job and produces output as below
dict1 = {"integervalue": 10, "floatingValue": 0, "stringValue": "XXX"}
or is there any better way to achieve without zip ?
Here's one way to achieve what I think you are after but it does not account for if there are multiple int, float, or str values in the dict2, it modifies the dict1 a bit, and it uses a third dictionary.
dict1 = {str: 'stringValue', int: 'integerValue', float: 'floatingValue'}
dict2 = {"0": 10, "1": 0.1020, "2": "XXX"}
output = {}
for k, v in dict2.items():
output.update({
dict1.get(type(v)): v
})
Output: {'integerValue': 10, 'floatingValue': 0.102, 'stringValue': 'XXX'}
EDIT Could also do for v in dict2.values() since I am not using the k variable.
Assuming the keys always have the same correspondence like in the example you showed, I'd actually make that explicit instead of relying on insertion ordering, which may cause problems. Something like:
key_translation = {
"integerValue": "0",
"floatingValue": "1",
"stringValue": "2"
}
dict1 = {"integerValue": None, "floatingValue": None, "stringValue": None}
dict2 = {"0": 10, "1": 0.1020, "2": "XXX"}
for key in dict1:
dict1[key] = dict2[key_translation[key]]
print(dict1)
# {'integerValue': 10, 'floatingValue': 0.102, 'stringValue': 'XXX'}

In Python, how do I find keys in an array of dictionaries where the values are the same?

I'm using Python 3.8. I have an array of dictionaries, all of which have the same keys ...
list_of_dicts = [{"a": 1, "b": 2}, {"a": 1, "b": "zz"}, {"a": 1, "b": "2"}]
How do I return a list of keys in which all the values are identical? For example, the above would be just
["a"]
since all three dicts have "a" = 1.
Here is my additional answer of #JaonHax.
array_of_dicts = [{"a": 1, "b": 2}, {"a": 1, "b": "zz", "c": "cc"}, {"a": 1, "b": "2"}]
def get_same_vals(dicts):
keys = []
for key in dicts[0].keys():
is_same = True
for each_dict in array_of_dicts:
if not key in each_dict or each_dict[key] != dicts[0][key]:
is_same = False
if is_same:
keys.append(key)
return keys
print(get_same_vals(array_of_dicts))
As suggested in other answers, create a master dictionary that groups each key, then check their uniqueness.
# all keys are the same, so get the list
keys = array_of_dicts[0].keys()
# collapse values into a single dictionary
value_dict = {k: set(d[k] for d in array_of_dicts) for k in keys}
# get list of all single-valued keys
print([k for k, v in value_dict.items() if len(v) == 1])
If you know for certain that they all have the same keys, you can iterate through their keys and the list like so:
array_of_dicts = [{"a": 1, "b": 2}, {"a": 1, "b": "zz"}, {"a": 1, "b": "2"}]
def get_same_vals(dicts):
keys = []
for key in dicts[0].keys():
is_same = True
for each_dict in dicts:
if each_dict[key] != dicts[0][key]:
is_same = False
if is_same:
keys.append(key)
return keys
print(get_same_vals(array_of_dicts))
# Prints ['a']
I apologise for the inefficient code; I didn't spend that long coding this up.
Here's a possible solution, it will work also in case that the dictionaries are differently structured (have different / extra keys):
array_of_dicts = [{"a": 1, "b": 2}, {"a": 1, "b": "zz"}, {"a": 1, "b": "2"}]
def is_entry_in_all_dicts(key, value):
identical_entries_found = 0
for dict in array_of_dicts:
if key in dict:
if dict[key] == value:
identical_entries_found += 1
if identical_entries_found == len(array_of_dicts):
return True
return False
result = []
for dict in array_of_dicts:
for key, value in dict.items():
if is_entry_in_all_dicts(key, value):
if key not in result:
result.append(key)
print(result)
Output
['a']
If every dictionary has the same keys, you can combine the values into sets and find the sets with one element:
[list(x.keys())[0] for x in [{k:set([e[k] for e in list_of_dicts])} for k in list_of_dicts[0]] if len(list(x.values())[0]) == 1]
Output:
['a']
Append your N dictionaries into a giant dictionary, and check for keys that have N identical values:
giant_dict = collections.defaultdict(list)
for k, v in (e for d in list_of_dicts for e in d):
giant_dict[k].append(v)
for k, v in giant_dict.items():
if len(v) == len(list_of_dicts) and all(e == v[0] for e in v):
print(k)
Here's a more succinct approach
from functools import reduce
array_of_dicts = [{"a": 1, "b": 2}, {"a": 1, "c": "zz"}, {"a": 1, "d": "2"}]
result = reduce(lambda a, b: a.intersection(b),list(map(lambda x: set(x.keys()),
array_of_dicts)))
Group your values into a set, then figure out which keys have a set with length 1:
>>> from collections import defaultdict
>>> list_of_dicts = [{"a": 1, "b": 2}, {"a": 1, "b": "zz"}, {"a": 1, "b": "2"}]
>>> grouped_values = defaultdict(set)
>>> for d in list_of_dicts:
... for k,v in d.items():
... grouped_values[k].add(v)
...
>>> [k for k,v in grouped_values.items() if len(v) == 1]
['a']

How to merge two nested dict in python?

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

Adding multiple values to an existing dictionary as SETS

I have a dictionary where I have the data already inside, i.e. keys have values and some of them have more than one value.
For example:
i = {"a": "111", "b": "222", "c": ["333", "444"]}
How can I change the type of the multiple values? I want them to be sets, not lists, such as:
i = {"a": {"111"}, "b": {"222"}, "c": {"333", "444"}}
One similar post is this one:
How to add multiple values to a dictionary key in python? [closed]
There it is explained how to add multiple elements to a dictionary, but they always seem to be lists.
How to change the type of the multiple values?
OR how to add them to the dictionary as sets, not lists?
Using a dict-comprehension makes converting an existing dict very easy:
i = {"a": "111", "b": "222", 'c': ["333", "444"]}
{k: set(v) if isinstance(v, list) else v for k, v in i.items()}
this converts all values that are lists to sets.
In a single line of code:
>>> i = {"a": "111", "b": "222", "c": ["333", "444"]}
>>> {k: set(v) for k, v in i.items()}
{'b': {'2'}, 'a': {'1'}, 'c': {'444', '333'}}
Or with a few more steps:
>>> i = {"a": "111", "b": "222", "c": ["333", "444"]}
>>> for k, v in i.items():
... i[k] = set(v)
>>> i
{'b': {'2'}, 'a': {'1'}, 'c': {'444', '333'}}
Instead of doing
my_dict['key'] = ['333', '444']
use a set literal:
my_dict['key'] = {'333', '444'}
That looks like a dict literal, but the lack of key: value like things makes it a set.

Categories

Resources