getting arrays of values from dictionary by key - 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 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]

Related

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

Working with Python nested dictionaries

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

item frequency in a python list of dictionaries

Ok, so I have a list of dicts:
[{'name': 'johnny', 'surname': 'smith', 'age': 53},
{'name': 'johnny', 'surname': 'ryan', 'age': 13},
{'name': 'jakob', 'surname': 'smith', 'age': 27},
{'name': 'aaron', 'surname': 'specter', 'age': 22},
{'name': 'max', 'surname': 'headroom', 'age': 108},
]
and I want the 'frequency' of the items within each column. So for this I'd get something like:
{'name': {'johnny': 2, 'jakob': 1, 'aaron': 1, 'max': 1},
'surname': {'smith': 2, 'ryan': 1, 'specter': 1, 'headroom': 1},
'age': {53:1, 13:1, 27: 1. 22:1, 108:1}}
Any modules out there that can do stuff like this?
collections.defaultdict from the standard library to the rescue:
from collections import defaultdict
LofD = [{'name': 'johnny', 'surname': 'smith', 'age': 53},
{'name': 'johnny', 'surname': 'ryan', 'age': 13},
{'name': 'jakob', 'surname': 'smith', 'age': 27},
{'name': 'aaron', 'surname': 'specter', 'age': 22},
{'name': 'max', 'surname': 'headroom', 'age': 108},
]
def counters():
return defaultdict(int)
def freqs(LofD):
r = defaultdict(counters)
for d in LofD:
for k, v in d.items():
r[k][v] += 1
return dict((k, dict(v)) for k, v in r.items())
print freqs(LofD)
emits
{'age': {27: 1, 108: 1, 53: 1, 22: 1, 13: 1}, 'surname': {'headroom': 1, 'smith': 2, 'specter': 1, 'ryan': 1}, 'name': {'jakob': 1, 'max': 1, 'aaron': 1, 'johnny': 2}}
as desired (order of keys apart, of course -- it's irrelevant in a dict).
items = [{'name': 'johnny', 'surname': 'smith', 'age': 53}, {'name': 'johnny', 'surname': 'ryan', 'age': 13}, {'name': 'jakob', 'surname': 'smith', 'age': 27}, {'name': 'aaron', 'surname': 'specter', 'age': 22}, {'name': 'max', 'surname': 'headroom', 'age': 108}]
global_dict = {}
for item in items:
for key, value in item.items():
if not global_dict.has_key(key):
global_dict[key] = {}
if not global_dict[key].has_key(value):
global_dict[key][value] = 0
global_dict[key][value] += 1
print global_dict
Simplest solution and actually tested.
New in Python 3.1: The collections.Counter class:
mydict=[{'name': 'johnny', 'surname': 'smith', 'age': 53},
{'name': 'johnny', 'surname': 'ryan', 'age': 13},
{'name': 'jakob', 'surname': 'smith', 'age': 27},
{'name': 'aaron', 'surname': 'specter', 'age': 22},
{'name': 'max', 'surname': 'headroom', 'age': 108},
]
import collections
newdict = {}
for key in mydict[0].keys():
l = [value[key] for value in mydict]
newdict[key] = dict(collections.Counter(l))
print(newdict)
outputs:
{'age': {27: 1, 108: 1, 53: 1, 22: 1, 13: 1},
'surname': {'headroom': 1, 'smith': 2, 'specter': 1, 'ryan': 1},
'name': {'jakob': 1, 'max': 1, 'aaron': 1, 'johnny': 2}}
This?
from collections import defaultdict
fq = { 'name': defaultdict(int), 'surname': defaultdict(int), 'age': defaultdict(int) }
for row in listOfDicts:
for field in fq:
fq[field][row[field]] += 1
print fq

Categories

Resources