Extract only values from a dicts inside a list - python

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

Related

To convert a dict (with list of keys and values) into list of dict

I have a dict with a list of keys, and the values are stored separate in a list of lists:
obj = {
'keys': ['key1', 'key2', 'key3'],
'items': [['value1', 'value2', 'value3'], ['value4', 'value5', 'value6'], ['value7', 'value8', 'value9']]
}
The desired output is to 'merge' them into a list of dict like this:
[
{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},
{'key1': 'value4', 'key2': 'value5', 'key3': 'value6'},
{'key1': 'value7', 'key2': 'value8', 'key3': 'value9'}
]
I have tried this direct approach
result = []
for item in obj['items']:
result.append(dict(zip(obj['keys'], item)))
and also shortened it to this
[dict(zip(obj['keys'], item)) for item in obj['items']]
Are there other alternatives to achieve the desired output?
And may I know what is the name of this 'merge' manipulation?
You can use pandas:
import pandas as pd
obj = {
'keys': ['key1', 'key2', 'key3'],
'items': [['value1', 'value2', 'value3'], ['value4', 'value5', 'value6'], ['value7', 'value8', 'value9']]
}
df = pd.DataFrame(obj['items'], columns=obj['keys'])
df.to_dict(orient='records')
result:
[{'key1': 'value1', 'key2': 'value2', 'key3': 'value3'},
{'key1': 'value4', 'key2': 'value5', 'key3': 'value6'},
{'key1': 'value7', 'key2': 'value8', 'key3': 'value9'}]
[ dict(zip(obj['keys'], item)) for item in obj['items'] ]
Your final line has a combination of these components:
list comprehension, ie, [ function(x) for x in list_x ]
zipping of 2 lists, ie, zip(list1, list2)
Perhaps these are the names of the 'merge' manipulation you are looking for?

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

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.

Python sort list of dicts with lists inside

I have the following list structure:
[
{'key1': 'value1',
'key2': [['mike', 'simmons', '54:17:47']],
'key3': 19390},
{'key1': 'value1',
'key2': [['snart', 'simmons', '60:12:47']],
'key3': 19390}
]
I would like to sort this list by the second index of the key2 key ( I mean, by those 60:12:47 numbers)
I haven't found a standard way of doing this..
Thanks!
Here is one way, assuming you want your values sorted as strings.
lst = [{'key1': 'value1', 'key2': [['snart', 'simmons', '60:12:47']], 'key3': 19390},
{'key1': 'value1', 'key2': [['mike', 'simmons', '54:17:47']], 'key3': 19390}]
res = sorted(lst, key=lambda x: x['key2'][0][2])
# [{'key1': 'value1', 'key2': [['mike', 'simmons', '54:17:47']], 'key3': 19390},
# {'key1': 'value1', 'key2': [['snart', 'simmons', '60:12:47']], 'key3': 19390}]
Use sorted with a comparator that uses that value:
sorted_list = sorted(my_list, key=lambda d: d['key2'][0][2])

Check if an element-hash exists in an array and update it, otherwise insert it

I have a list of hashes:
[
{'key1': 'value1', 'key2': some_object},
{'key1': 'value21', 'key2': some_object2},
{'key1': 'value133', 'key2': some_object3}
]
What's the easiest way to check if an element with 'key1': 'value133' exists (if my case it does) and update it, (say 'key1': 'value133', 'key2': some_object333} otherwise insert it ({'key1': 'value133', 'key2': some_object3})?
l = [
{'key1': 'value1', 'key2': 'some_object'},
{'key1': 'value21', 'key2': 'some_object2'},
{'key1': 'value133', 'key2': 'some_object3'}
]
d = any(d for d in l if d['key1'] == 'value133')
if d:
d['key2'] = 'some_object333'
else :
l.append({'key1': 'value133', 'key2': 'some_object3'})
print(d)
do something like this use any()

Categories