Working with Python nested dictionaries - python

I've got a dictionary (teamDictionary) that is seeded with names, teams, and statuses of team members:
teamDictionary = {
1: {'name': 'Bob', 'team': 'A', 'status': 'Leave'},
2: {'name': 'George', 'team': 'C', 'status': 'Training'},
3: {'name': 'Sam', 'team': 'B', 'status': 'Travel'},
4: {'name': 'Phil', 'team': 'A', 'status': 'Leave'},
5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}
}
How can I query the dictionary of dictionaries so that I can get the names of:
All team members from Team A that are out on Leave, or
All team members from Team B that are in a Travel status, or
All team members from Team C that are in Training
Thanks in advance!

I think list comprehensions with the conditions you want would look clean:
team_A_on_leave = [player['name'] for player in teamDictionary.values()
if player['team'] == 'A'
and player['status'] == 'leave']
The other 2 scenarios would be similar list comprehensions with different conditions.

We can filter the dictionary:
keys = filter(lambda x: teamDictionary.get(x).get('team') == 'A' and teamDictionary.get(x).get('status') == 'Leave', teamDictionary)
filtered_a = {k: teamDictionary.get(k) for k in keys}
{1: {'name': 'Bob', 'status': 'Leave', 'team': 'A'},
4: {'name': 'Phil', 'status': 'Leave', 'team': 'A'}}
You would just change the conditions based on the values you want to check for in the inner dictionaries.

You can try this:
teamDictionary = {
1: {'name': 'Bob', 'team': 'A', 'status': 'Leave'},
2: {'name': 'George', 'team': 'C', 'status': 'Training'},
3: {'name': 'Sam', 'team': 'B', 'status': 'Travel'},
4: {'name': 'Phil', 'team': 'A', 'status': 'Leave'},
5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}
}
a_leave = [b['name'] for a, b in teamDictionary.items() if b['team'] == 'A' and b['status'] == 'Leave']
b_travel = [b['name'] for a, b in teamDictionary.items() if b['team'] == 'B' and b['status'] == 'Travel']
c_training = [b['name'] for a, b in teamDictionary.items() if b['team'] == 'C' and b['status'] == "Training']

Related

getting arrays of values from dictionary by key

I have dictionary:
teamDictionary = {
1: {'name': 'Bob', 'team': 'A', 'status': 'Leave'},
2: {'name': 'George', 'team': 'C', 'status': 'Training'},
3: {'name': 'Sam', 'team': 'B', 'status': 'Travel'},
4: {'name': 'Phil', 'team': 'A', 'status': 'Leave'},
5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}
}
I need to get array of names:
['Bob','George','Sam','Phil','Georgia']
How shold I solve my problem?
Using a list comprehension you can
Get the values in the dictionary.
For each of the values, get the name
TeamDictionary = {
1: {'name': 'Bob', 'team': 'A', 'status': 'Leave'},
2: {'name': 'George', 'team': 'C', 'status': 'Training'},
3: {'name': 'Sam', 'team': 'B', 'status': 'Travel'},
4: {'name': 'Phil', 'team': 'A', 'status': 'Leave'},
5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}
}
print([x['name'] for x in TeamDictionary.values()])
> ['Bob', 'George', 'Sam', 'Phil', 'Georgia']
This will work:
names = [value['name'] for key, value in teamDictionary.items()]
You can easyly do this in one line using array comprehension.
names = [item['name'] for item in teamDictionary.values()]
you can iterate through the dictionary keys and for each item you can 'take' the name property like:
names = [teamDictionary[key]['name'] for key in teamDictionary]

getting part of dictionary by value in python

I have dictionary:
teamDictionary = {
1: {'name': 'Bob', 'team': 'A', 'status': 'Leave'},
2: {'name': 'George', 'team': 'C', 'status': 'Training'},
3: {'name': 'Sam', 'team': 'B', 'status': 'Travel'},
4: {'name': 'Phil', 'team': 'A', 'status': 'Leave'},
5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}
}
I need to get all smaller dictionary where team is C. My cod is:
team_leave = [teamDictionary[a] for a, b in teamDictionary.items() if b['team'] == 'C' ]
print(team_leave)
[{'name': 'George', 'team': 'C', 'status': 'Training'}, {'name': 'Georgia', 'team': 'C', 'status': 'Training'}]
But I need to get
{
2: {'name': 'George', 'team': 'C', 'status': 'Training'},
5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}
}
How should I solve my problem?
You can use a dict comprehension instead:
{k: d for k, d in teamDictionary.items() if d['team'] == 'C'}
You should use Dictionary Comprehension:
team_leave = {key: item for key, item in teamDictionary.items() if item['team'] == 'C'}
print(team_leave)
Ouput:
{2: {'name': 'George', 'team': 'C', 'status': 'Training'}, 5: {'name': 'Georgia', 'team': 'C', 'status': 'Training'}}
print({key: values for key, values in teamDictionary.items() if values['team'] == 'C'}

Remove duplicates from a list of dicts

I have a list of dicts like this:
[{'ID': 'a', 'Number': 2}, {'ID': 'b', 'Number': 5} , {'ID': 'a', 'Number': 6}, {'ID': 'a', 'Number': 8}, {'ID': 'c', 'Number': 3}]
I want to remove the dicts that have same key and only keep the one with smallest value. The expected result should be:
[{'ID': 'a', 'Number': 2}, {'Id': 'b', 'Number': 5}, {'ID': 'c', 'Number': 3}]
Most efficient solution would be to use a temporary lookup dictionary with keys as IDs and values as the current dict which has the lowest Number corresponding to that ID.
l = [{'ID': 'a', 'Number': 2},
{'ID': 'b', 'Number': 5}, # note that I corrected a typo Id --> ID
{'ID': 'a', 'Number': 6},
{'ID': 'a', 'Number': 8},
{'ID': 'c', 'Number': 3}]
lookup_dict = {}
for d in l:
if d['ID'] not in lookup_dict or d['Number'] < lookup_dict[d['ID']]['Number']:
lookup_dict[d['ID']] = d
output = list(lookup_dict.values())
which gives output as:
[{'ID': 'a', 'Number': 2}, {'ID': 'b', 'Number': 5}, {'ID': 'c', 'Number': 3}]
A piece of advice: given your final data structure, I wonder if you may be better off now representing this final data as a dictionary - with the IDs as keys since these are now unique. This would allow for more convenient data access.

Using Glom on a nested structure, how to I move top level dictionary fields into a list of dictionaries?

This is a question about the usage of Glom (https://github.com/mahmoud/glom/)
I have a dictionary that includes a list of other dictionaries.
{'date': '2020-01-01',
'location': 'A',
'items': [
{'name': 'A', 'id': 'A1'},
{'name': 'B', 'id': 'B1'},
{'name': 'C', 'id': 'C1'}
]}
I would like to use Glom to move the outer, global dictionary fields 'date' and 'location' into list of dictionaries for the items.
This is the end result I try to reach
[
{'name': 'A', 'id': 'A1', 'date': '2020-01-01', 'location': 'A'},
{'name': 'B', 'id': 'B1', 'date': '2020-01-01', 'location': 'A'},
{'name': 'C', 'id': 'C1', 'date': '2020-01-01', 'location': 'A'}
]
Alas, when the spec arrives at the 'item' of the dictionary, the other values are not longer accessable and the T object is set to the inner value instead.
from glom import glom, T
def update_dict(x, other_dict):
x.update({'date': other_dict['date'], 'location': other_dict['location']})
return x.copy()
spec = (T, 'items', [(lambda x: update_dict(x, T()))])
data = {'date': '2020-01-01',
'location': 'A',
'items': [{'name': 'A', 'id': 'A1'},
{'name': 'B', 'id': 'B1'},
{'name': 'C', 'id': 'C1'}]}
glom(data, spec) # print this
returns
[{'name': 'A', 'id': 'A1', 'date': T()['date'], 'location': T()['location']},
{'name': 'B', 'id': 'B1', 'date': T()['date'], 'location': T()['location']},
{'name': 'C', 'id': 'C1', 'date': T()['date'], 'location': T()['location']}]
Which is useless.
It's not difficult to update the dictionaries with regular Python code, but
is there a way to do this within a Glom spec?
The trick is to pass the target as a global scope as well,
this way, the Assign command can access the full target.
from glom import S, glom, Assign, Spec
spec = ('items',
[Assign( 'date', Spec(S['date']))],
[Assign( 'location', Spec(S['location']))]
)
target = {'date': '2020-04-01',
'location': 'A',
'items': [
{'name': 'A', 'id': 'A1'},
{'name': 'B', 'id': 'B1'},
{'name': 'C', 'id': 'C1'}
]}
spec = Spec(('items', [Assign( 'date', Spec(S['date']))], [Assign( 'location', Spec(S['location']))]))
glom(target, spec, scope=target)
Results in
[{'name': 'A', 'id': 'A1', 'date': '2020-04-01', 'location': 'A'},
{'name': 'B', 'id': 'B1', 'date': '2020-04-01', 'location': 'A'},
{'name': 'C', 'id': 'C1', 'date': '2020-04-01', 'location': 'A'}]

How do I merge multiple dictionaries values having same key in python?

I have n number of dicts like this :
dict_1 = {1: {'Name': 'xyz', 'Title': 'Engineer'}, 2: {'Name': 'abc',
'Title': 'Software'}}
dict_2 = {1: {'Education': 'abc'}, 2: {'Education': 'xyz'}}
dict_3 = {1: {'Experience': 2}, 2:{'Experience': 3}}
.
.
.
dict_n
I just want to combine all of them based on main key like this :
final_dict = {1: {'Name': 'xyz', 'Title': 'Engineer', 'Education':
'abc', 'Experience': 2},
2: {'Name': 'abc', 'Title': 'Software', 'Education':
'xyz', 'Experience': 3}}
can anybody help me to achieve this ?
from your question I think you have n number of dicts. So make list of your dicts and combine all the values having same key. But that itself won't give the exact answer. They are list of dicts. So the second thing I have done is make all those small dicts to one dict .
Here my code you can check :
d1 = {1: {'Name': 'xyz', 'Title': 'Engineer'}, 2: {'Name': 'abc',
'Title': 'Software'}}
d2 = {1: {'Education': 'abc'}, 2: {'Education': 'xyz'}}
d3 = {1: {'Experience': 2}, 2:{'Experience': 3}}
ds = [d1, d2, d3] # list of your dicts you can change it to dict_
big_dict = {}
for k in ds[0]:
big_dict[k] = [d[k] for d in ds]
for k in big_dict.keys():
result = {}
for d in big_dict[k]:
result.update(d)
big_dict[k] = result
print(big_dict)
It gives O/P like this :
{
1: {'Education': 'abc', 'Title': 'Engineer', 'Name': 'xyz',
'Experience': 2},
2: {'Education': 'xyz', 'Title': 'Software', 'Name': 'abc',
'Experience': 3}
}

Categories

Resources