How to duplicate dictionary with 0 values - python

What I can do:
dict1 = {'key1':0, 'key2':10, 'key3':110}
dict2 = dict(dict1)
for key in dict2:
dict2[key] = 0
print(dict2) # {'key1':0, 'key2':0, 'key3':0}
Is there a simple way to do that?

Simplest, using dict comprehension :
>>> {k:0 for k in dict1}
# driver values :
IN : dict1 = {'key1':0, 'key2':10, 'key3':110}
OUT : {'key1':0, 'key2':0, 'key3':0}

Yes. Use dict.fromkeys:
>>> dict1 = {'key1':0, 'key2':10, 'key3':110}
>>> dict.fromkeys(dict1, 0)
{'key1': 0, 'key2': 0, 'key3': 0}
Be careful, though, if your fill-value is a mutable object, this will mean every value will be the same instance of that mutable object, e.g.:
>>> new_dict = dict.fromkeys(dict1, [])
>>> new_dict
{'key1': [], 'key2': [], 'key3': []}
>>> new_dict['key1'].append('foo')
>>> new_dict
{'key1': ['foo'], 'key2': ['foo'], 'key3': ['foo']}

dict1 = {'key1':0, 'key2':10, 'key3':110}
dict2 = dict((i,0) for i in dict1)
Result:
{'key3': 0, 'key2': 0, 'key1': 0}

Related

make a dictionary from lists

I have following lists.
keys = ["key1", "key2", "key3"]
value1 = [1,2]
value2 = [10,20]
value3 = [100,200]
How can I get the result like [{"key1":1, "key2":10, "key3":100},{"key1":2, "key2":20, "key3":200}] using python?
I tried for loops but I couldn't find any solution.
Thanks in advance
You can use a list comprehension to first zip your values elementwise, then create dictionaries by zipping those against your keys.
>>> [dict(zip(keys, i)) for i in zip(value1, value2, value3)]
[{'key1': 1, 'key2': 10, 'key3': 100}, {'key1': 2, 'key2': 20, 'key3': 200}]
You can do this by using for loop. Like this
keys = ["key1", "key2", "key3"]
value1 = [1,2]
value2 = [10,20]
value3 = [100,200]
values = [value1, value2, value3]
output = [{}, {}]
for i in range(len(keys)):
output[0][keys[i]] = values[i][0]
output[1][keys[i]] = values[i][1]
print(output)
Output
[{'key1': 1, 'key2': 10, 'key3': 100}, {'key1': 2, 'key2': 20, 'key3': 200}]

Extract only values from a dicts inside a list

How to extract every value from each dictionary nested within a list?
Currently I'm stuck with a list comprehension that accepts one key.
d = [e["key1"] for e in list]
Sample
[{'key1': 'value1', 'key2': 'value2'}, {'key3': 'value4', 'key4': 'value4'}]
Need to get
value1, value2, value3, value4
>>> vals = []
>>> for d in d_list:
vals += list(d.values())
>>> vals
['value1', 'value2', 'value4', 'value4']
via itertools chain -
l = [{'key1': 'value1', 'key2': 'value2'}, {'key3': 'value4', 'key4': 'value4'}]
from itertools import chain
result = list(chain(*(item.values() for item in l)))
Via list comprehension -
result = [val for i in l for val in i.values()]
Thanks to all and #kaya3!
[x for d in list_of_dicts for x in d.values()]

Looping over nested dictionary and delete if condition is not met (python)

I have a list of nested dictionaries:
[{'a': 1,
'b': 'string',
'c': [{'key1': 80,
'key2': 'string',
'key3': 4033},
{'key1': 324,
'key2': 'string',
'key3': 4034,
'key4': 1}]},
{'a': 1,
'b': 'string',
'c': [{'key1': 80,
'key2': 'string',
'key3': 4033},
{'key1': 324,
'key2': 'string',
'key3': 4034,
'key4': 1,
'key5': 2}]}]
Please not that the values of key c is a list of dictionaries again.
Now I want to filter out from this list all dictionaries with key c, that do not contain key1, key2, key3 & key4.
I thought of looping first over the first, second, and so on dict in the list, and then looping over the nested dicts that have c as a key. Then, if the dict inside c does not meet my requirement, I delete it.
Therefore my code would be:
for j in range(len(mydict)):
for i in range(len(mydict[j]["c"])):
if not all (k in mydict[j]["c"][i] for k in ("key1", "key2", "key3", "key4")):
del(mydict[j]["c"][i])
But I am getting a IndexError: list index out of range error. Where is my mistake?
My desired output would be:
[{'a': 1,
'b': 'string',
'c': [{'key1': 324,
'key2': 'string',
'key3': 4034,
'key4': 1}]},
{'a': 1,
'b': 'string',
'c': [{'key1': 324,
'key2': 'string',
'key3': 4034,
'key4': 1,
'key5': 2}]}]
The problem is that with for i in range(len(mydict[j]["c"])): you are iterating the lists in the dict while at the same time removing from those lists. Instead, you can replace the inner loop with a list comprehension:
for d in mydict:
d['c'] = [d2 for d2 in d['c']
if all(k in d2 for k in ("key1", "key2", "key3", "key4"))]
Just to have another option:
keep = {'key1', 'key2', 'key3', 'key4'}
for h in mydict:
h['c'] = [ e for e in h['c'] if len(keep - set(e.keys())) == 0 ]
If you wanted another perspective on it:
def remove_keys(mydict):
mydict2 = mydict
keys = ['key1', 'key2', 'key3', 'key4']
for xIndex, x in enumerate(mydict):
for yIndex, y in enumerate(x['c']):
if not all(key in y.keys() for key in keys):
del mydict2[xIndex]['c'][yIndex]
return mydict2
Returns a new dictionary with the modifications.

Merging python dictionaries based on value comparing

I have two dictionaries :
dict1 = {'key1': [val, val, val], 'key2': [val, val, val]}
dict2 = {'key1': [val, val, val], 'key2': [val, val, val]}
I need to find in dict1 and dict2 keys with the same values and create a new dict with that keys (dicr3 = {'key1': key1}). Is there better way to do this instead of double for loop?
for key, val in first_dict.items():
for key2, val2 in sec_dict.items():
if val == val2:
print(str(key) + " : " + str(key2))
You could convert your values to tuples. This way, they become hashable and you can put them into a dict:
dict1 = {'key1': [1,2,3], 'key2': [3,4,5]}
dict2 = {'key3': [2,3,4], 'key4': [1,2,3]}
same_lists = {}
for d in [dict1, dict2]:
for k, v in d.items():
same_lists.setdefault(tuple(v), []).append(k)
print(same_lists)
# {(1, 2, 3): ['key1', 'key4'], (3, 4, 5): ['key2'], (2, 3, 4): ['key3']}
Now you only need to iterate over the values of your dict and look for multiple keys:
for common_keys in same_lists.values():
if len(common_keys) > 1:
print(common_keys)
# ['key1', 'key4']
This solution is O(n), compared to your O(n**2) code.
What about this one:
{key1: key2 for key1, value1 in dict1.items() for key2, value2 in dict2.items() if value1 == value2}
Is there better way to do this instead of double for loop?
Yes, you could use the zip function instead.
dict1 = {'key1': [1, 2, 3], 'key2': [4, 5, 6]}
dict2 = {'key1': [4, 5, 6], 'key2': [7, 8, 9]}
for k1, k2 in zip(dict1, dict2):
pass
It's unclear what merge operation you are trying to achieve, therefore I will let you handle your own case but set are a good way to perform merge operations.

How can I merge two nested dictionaries together?

I've got two nested dictionaries that have overlapping keys at the first level, but different keys at the second level. I want to merge them, so that the new dictionary has all of the keys.
A = {'id1': {'key1': 1, 'key2': 2 }, 'id2':{'key1': 3, 'key2': 4 }}
B = {'id1': {'key3': 5}, 'id2': {'key3': 6}}
The result should be
A_B = {'id1': {'key1': 1, 'key2': 2, 'key3': 5}, 'id2':{'key1': 3, 'key2': 4, 'key3': 6}}
I know that I could do a for loop
for key in A:
A[key].update(B[key])
But I would like to know if there is a cleaner solution.
You could merge them in a dictionary comprehension:
A_B = {k: dict(A.get(k, {}), **B.get(k, {})) for k in A.viewkeys() | B.viewkeys()}
This uses the Python 2 dictionary keys view object; in Python 3, use dict.keys() instead of dict.viewkeys().
This'll merge all keys even if they are only present in one or the other of the dictionaries.
Demo with your input:
>>> A = {'id1': {'key1': 1, 'key2': 2 }, 'id2':{'key1': 3, 'key2': 4 }}
>>> B = {'id1': {'key3': 5}, 'id2': {'key3': 6}}
>>> {k: dict(A.get(k, {}), **B.get(k, {})) for k in A.viewkeys() | B.viewkeys()}
{'id2': {'key3': 6, 'key2': 4, 'key1': 3}, 'id1': {'key3': 5, 'key2': 2, 'key1': 1}}
or with input with more varied keys:
>>> C = {'foo': {'spam': 1, 'ham': 2}, 'bar': {'spam': 43, 'eggs': 81}}
>>> D = {'baz': {'vikings': 'singing'}, 'bar': {'monty': 'python'}}
>>> {k: dict(C.get(k, {}), **D.get(k, {})) for k in C.viewkeys() | D.viewkeys()}
{'bar': {'eggs': 81, 'monty': 'python', 'spam': 43}, 'foo': {'ham': 2, 'spam': 1}, 'baz': {'vikings': 'singing'}}
Iterate dictionary B
Check if key from the B is present in the A- Exception Handling
If yes, then Update respective value of A by B.
If Not, then Add New Key with value in A
code:
>>> A = {'id1': {'key1': 1, 'key2': 2 }, 'id2':{'key1': 3, 'key2': 4 }}
>>> B = {'id1': {'key3': 5}, 'id2': {'key3': 6}}
>>> for i, j in B.items():
... if i in A:
... A[i].update(j)
... else:
... A[i] = j
...
>>> A
{'id2': {'key3': 6, 'key2': 4, 'key1': 3}, 'id1': {'key3': 5, 'key2': 2, 'key1': 1}}
>>>

Categories