make a dictionary from lists - python

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

Related

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()]

How to add multiple values of same key in python dictionary

I have dictionary like this.
dict1 = {'key1': [1,2,3,4] , 'key2': [5,6,7]}
I want output like this.
dict1 = {'key1': 10 , 'key2': 18}
dict1 = {'key1': [1,2,3,4] , 'key2': [5,6,7]}
{k:sum(v) for k,v in dict1.items()}
First your extract the keys and values from your dictionary, then you sum the values as output.
dict1.items()
dict_items([('key1', [1, 2, 3, 4]), ('key2', [5, 6, 7])])
As you can see you get a tuple. By saying for k,v in dict1.items(), you are extracting those k,v then you are summing the v...
Hope you understand.

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.

How to duplicate dictionary with 0 values

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}

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.

Categories