group few lists of dictionary by key - python

lst1 = [
{"id": "A", "a": "one"},
{"id": "B", "b": "two"}
]
lst2 = [
{"id": "A", "a1": "Three"},
{"id": "B", "b1": "Four"},
{"id": "C", "c1": "Four"}
]
lst3 = [
{"id": "A", "c1": "Five"},
{"id": "B", "d1": "Six"}
]
a = lst1+lst2+lst3
res = [
{'id': 'A', 'a': 'one'},
{'id': 'B', 'b': 'two'},
{'id': 'A', 'a1': 'Three'},
{'id': 'B', 'b1': 'Four'},
{'id': 'C', 'c1': 'Four'},
{'id': 'A', 'c1': 'Five'},
{'id': 'B', 'd1': 'Six'}
]
I want to group by Id the res will look like this
res = [
{'id': 'A', 'a': 'one','a1': 'Three','c1': 'Five'},
{'id': 'B', 'b': 'two', 'b1': 'Four', 'd1': 'Six'},
{'id': 'C', 'c1': 'Four'},
]
What I have tried:
result = []
for l1, l2,l3 in zip(lst1, lst2,lst3):
result.append({**l1 , **l2 , **l3})
print(result)

Here's one approach:
arr = [
{'id': 'A', 'a': 'one'},
{'id': 'B', 'b': 'two'},
{'id': 'A', 'a1': 'Three'},
{'id': 'B', 'b1': 'Four'},
{'id': 'C', 'c1': 'Four'},
{'id': 'A', 'c1': 'Five'},
{'id': 'B', 'd1': 'Six'}
]
res_dict = {d['id']:{'id':d['id']} for d in arr}
for d in arr:
res_dict[d['id']].update(d)
res = list(res_dict.values())
The resulting list res:
[{'id': 'A', 'a': 'one', 'a1': 'Three', 'c1': 'Five'},
{'id': 'B', 'b': 'two', 'b1': 'Four', 'd1': 'Six'},
{'id': 'C', 'c1': 'Four'}]

def coalesce(updates: list[dict[str,str]], join_key):
res = {}
for upd in updates:
for rec in upd:
key = rec[join_key]
if not key in res:
res[key] = {join_key: key}
res[key].update(rec)
return res.values()
recs = [lst1, lst2, lst3]
for value in coalesce(recs, "id"):
print(value)

Related

How to match two lists and insert into specific value?

I have two lists
a = ['b','c','a','d','v']
g = [{'c':'1'},{'c':'2'},{'c':'3'},{'d':'1'},{'d':'2'}]
I want to match the key in the dictionary in the list g to the elements in list a, if they are matched, the elements in list g will be inserted into list a.
The desired outcome is:
['b','c',{'c':'1'},{'c':'2'},{'c':'3'},'a','d',{'d':'1'},{'d':'2'},'v']
Try:
a = ["b", "c", "a", "d", "v"]
g = [{"c": "1"}, {"c": "2"}, {"c": "3"}, {"d": "1"}, {"d": "2"}]
tmp = {}
for d in g:
for k in d:
tmp.setdefault(k, []).append(d)
out = []
for v in a:
out.append(v)
out.extend(tmp.get(v, []))
print(out)
Prints:
['b', 'c', {'c': '1'}, {'c': '2'}, {'c': '3'}, 'a', 'd', {'d': '1'}, {'d': '2'}, 'v']
Try using sorted:
print(sorted(a + g, key=lambda x: list(x)[0]))
Output:
['a', 'b', 'c', {'c': '1'}, {'c': '2'}, {'c': '3'}, 'd', {'d': '1'}, {'d': '2'}, 'e']
a = ['a','b','c','d','e']
g = [{'c':'1'},{'c':'2'},{'c':'3'},{'d':'1'},{'d':'2'},{'z':'1'}]
for dic in g:
for key in dic:
if key in a:
a.append(dic)
print(a)
#output ['a', 'b', 'c', 'd', 'e', {'c': '1'}, {'c': '2'}, {'c': '3'}, {'d': '1'}, {'d': '2'}]
After this, you can do sorting using lambda if required.

How to select only specific key-value pairs from a list of dictionaries?

This is my example :
dictlist = [{'Name': 'James', 'city': 'paris','type': 'A' },
{'Name': 'James','city': 'Porto','type': 'B'},
{'Name': 'Christian','city': 'LA','type': 'A'}]
I want to filter specific keys and values.
For example:
desiredKey = [Name,type]
desiredoutput = [{'Name': 'Lara', 'type': 'A' },
{'Name': 'James', 'type': 'B'},
{'Name': 'Christian','type': 'A'}]
I tried this, but it doesn't work
keys = dictlist[0].keys()
output= [d for d in dictlist if d.keys in desiredKey]
You can try something like this:
In [1]: dictlist = [{'Name': 'James', 'city': 'paris','type': 'A' },
...: {'Name': 'James','city': 'Porto','type': 'B'},
...: {'Name': 'Christian','city': 'LA','type': 'A'}]
In [2]: keys = ["Name","type"]
In [3]: res = []
In [5]: for dict1 in dictlist:
...: result = dict((k, dict1[k]) for k in keys if k in dict1)
...: res.append(result)
...:
In [6]: res
Out[6]:
[{'Name': 'James', 'type': 'A'},
{'Name': 'James', 'type': 'B'},
{'Name': 'Christian', 'type': 'A'}]
It's a bit more complicated than this answer but you can also use zip and itemgetter.
In [43]: list_of_dicts = [
...: {"a":1, "b":1, "c":1, "d":1},
...: {"a":2, "b":2, "c":2, "d":2},
...: {"a":3, "b":3, "c":3, "d":3},
...: {"a":4, "b":4, "c":4, "d":4}
...: ]
In [44]: allowed_keys = ("a", "c")
In [45]: filter_func = itemgetter(*allowed_keys)
In [46]: list_of_filtered_dicts = [
...: dict(zip(allowed_keys, filter_func(d)))
...: for d in list_of_dicts
...: ]
In [47]: list_of_filtered_dicts
Out[47]: [{'a': 1, 'c': 1}, {'a': 2, 'c': 2}, {'a': 3, 'c': 3}, {'a': 4, 'c': 4}]

Build nested Python dictionary from flatten dictionary

I have the following flatten dictionary containing one entry for each item and each item contains a parent and children attribute.
{
'a': {
parent: None,
children: ['b', 'c', 'd']
},
'b': {
parent: 'a',
children: ['e', 'f', 'g']
},
'c': {
parent: 'a',
children: []
},
'd': {
parent: 'a',
children: []
},
'e': {
parent: 'b',
children: []
},
'f': {
parent: 'b',
children: ['h']
},
'g': {
parent: 'b',
children: []
},
'h': {
parent: 'f',
children: []
},
}
How can I turn it into a nested dictionary which looks like this?
{
'a': {
'b': {
'e': {},
'f': {
'h':
}
'g': {}
},
'c': {},
'd': {},
}
}
You can use recursion:
d = {'a': {'parent': None, 'children': ['b', 'c', 'd']}, 'b': {'parent': 'a', 'children': ['e', 'f', 'g']}, 'c': {'parent': 'a', 'children': []}, 'd': {'parent': 'a', 'children': []}, 'e': {'parent': 'b', 'children': []}, 'f': {'parent': 'b', 'children': ['h']}, 'g': {'parent': 'b', 'children': []}, 'h': {'parent': 'f', 'children': []}}
def group(start=None):
return {a:group(a) for a, b in d.items() if b['parent'] == start}
import json
print(json.dumps(group(), indent=4))
Output:
{
"a": {
"b": {
"e": {},
"f": {
"h": {}
},
"g": {}
},
"c": {},
"d": {}
}
}

Get list of common dictionaries from List of dictionaries on one key value match

I am trying to merge the list of dictionaries inside a list based on a value of key "host". The sample input for the same looks like:
first = [{'host': '1', 'a': 'a', 'b': 'b'}, {'host': '2', 'a': 'c', 'd': 'd'}, {'host': '3', 'a': 'd', 'd': 'd'}]
second = [{'host': '1', 'a': 'w', 'b': 'e'}, {'host': '2', 'a': 'q', 'd': 's'}, {'host': '3', 'a': 'q', 'd': 'c'}]
third= [{'host': '1', 'a': 'r', 'b': 't'}, {'host': '2', 'a': 'f', 'd': 'b'}, {'host': '3', 'a': 'k', 'd': 'p'}]
I am trying to get output like this
final_list = {
"1": [
{ "host": "1", "a": "a", "b": "b" },
{ "host": "1", "a": "w", "b": "e" },
{ "host": "1", "a": "r", "b": "t" }
],
"2": [
{ "host": "2", "a": "c", "d": "d" },
{ "host": "2", "a": "q", "d": "s" },
{ "host": "2", "a": "f", "d": "b" }
],
"3": [
{ "host": "3", "a": "d", "d": "d" },
{ "host": "3", "a": "q", "d": "c" },
{ "host": "3", "a": "k", "d": "p" }
]
}
You want to zip them pairwise and then use enumerate to annotate the pairs starting at 1.
final_list = {str(num): [a, b, c] for num, (a, b, c) in
enumerate(zip(first, second, third), start = 1)}
>>> final_list
{'1': [{'a': 'a', 'b': 'b', 'host': '1'},
{'a': 'w', 'b': 'e', 'host': '1'},
{'a': 'r', 'b': 't', 'host': '1'}],
'2': [{'a': 'c', 'd': 'd', 'host': '2'},
{'a': 'q', 'd': 's', 'host': '2'},
{'a': 'f', 'd': 'b', 'host': '2'}],
'3': [{'a': 'd', 'd': 'd', 'host': '3'},
{'a': 'q', 'd': 'c', 'host': '3'},
{'a': 'k', 'd': 'p', 'host': '3'}]}
I gathered your List for simpler use and you can do that:
first = [{'host': '1', 'a': 'a', 'b': 'b'}, {'host': '2', 'a': 'c', 'd': 'd'}, {'host': '3', 'a': 'd', 'd': 'd'}]
second = [{'host': '1', 'a': 'w', 'b': 'e'}, {'host': '2', 'a': 'q', 'd': 's'}, {'host': '3', 'a': 'q', 'd': 'c'}]
third= [{'host': '1', 'a': 'r', 'b': 't'}, {'host': '2', 'a': 'f', 'd': 'b'}, {'host': '3', 'a': 'k', 'd': 'p'}]
final_dict = {}
allList = [first, second, third]
for aList in allList:
for aDict in aList:
if aDict["host"] not in final_dict.keys():
final_dict[aDict["host"]] = [aDict]
else:
final_dict[aDict["host"]].append([aDict])
print(final_dict)

python - split array of objects

I have a data structure that looks like this
arrayObjects = [{id: 1, array1: [a,b,c]}, {id: 2, array1: [d,e,f]}]
and would like to transform it into this:
newArrayObjects = [{id: 1, term: a}, {id:1, term: b}, ... {id:2, term: f} ]
any idea on how to do this?
this is my minimum version right now:
for item in arrayObjects:
for term in item['array1']:
print(term, item['id'])
to clarify: I know how to do this with a nested loop, I'm just going for the most pythonic version possible haha
You can use list comprehension:
>>> a = [{'id': 1, 'array': ['a','b','c']}, {'id': 2, 'array': ['d','e','f']}]
>>> [{'id': d['id'], 'term': v } for d in a for v in d['array']]
[{'term': 'a', 'id': 1}, {'term': 'b', 'id': 1}, {'term': 'c', 'id': 1}, {'term': 'd', 'id': 2}, {'term': 'e', 'id': 2}, {'term': 'f', 'id': 2}]

Categories

Resources