tags:

views:

53

answers:

2

In Python, I have a list of dicts as follows:

orig_list = [{'first_name': u'Jake', 'last_name': u'Sarson', 'display_name': u'AVG', 'team': u'TeamOne', 'value': 7.0}, {'first_name': u'Mike', 'last_name': u'Walsh', 'display_name': u'AVG', 'team': u'TeamTwo', 'value': 12.0}, {'first_name': u'Jake', 'last_name': u'Sarson', 'display_name': u'AVG', 'team': u'TeamOne', 'value': 7.0}, 
{'first_name': u'Mike', 'last_name': u'Walsh', 'display_name': u'AVG', 'team': u'TeamTwo', 'value': 12.0}, {'first_name': u'Steve', 'last_name': u'Mottola', 'display_name': u'AVG', 'team': u'TeamTwo', 'value': 18.0}, {'first_name': u'Steve', 'last_name': u'Mottola', 'display_name': u'AVG', 'team': u'TeamTwo', 'value': 18.0}, {'first_name': u'Craig', 'last_name': u'Schubert', 'display_name': u'AVG', 'team': u'TeamOne', 'value': 23.5}, 
{'first_name': u'Steve', 'last_name': u'Mottola', 'display_name': u'REC', 'team': u'TeamTwo', 'value': 2.0}, {'first_name': u'Mike', 'last_name': u'Walsh', 'display_name': u'REC', 'team': u'TeamTwo', 'value': 1.0}, {'first_name': u'Jake', 'last_name': u'Sarson', 'display_name': u'REC', 'team': u'TeamOne', 'value': 1.0}, {'first_name': u'Craig', 'last_name': u'Schubert', 'display_name': u'REC', 'team': u'TeamOne', 'value': 2.0}, {'first_name': u'Craig', 'last_name': u'Schubert', 'display_name': u'TD', 'team': u'TeamOne', 'value': 1.0}, {'first_name': u'Steve', 'last_name': u'Mottola', 'display_name': u'YDS', 'team': u'TeamTwo', 'value': 36.0}, {'first_name': u'Jake', 'last_name': u'Sarson', 'display_name': u'YDS', 'team': u'TeamOne', 'value': 7.0}, {'first_name': u'Mike', 'last_name': u'Walsh', 'display_name': u'YDS', 'team': u'TeamTwo', 'value': 12.0}, 
{'first_name': u'Craig', 'last_name': u'Schubert', 'display_name': u'YDS', 'team': u'TeamOne', 'value': 47.0]

I need to create a new list of dicts from the first list to find the unique names and for each name find all the display_name's and the values. In essence the result should be:

[{'first_name': u'Jake', 'last_name': u'Sarson', 'team': u'TeamOne', 'AVG': 7.0, 'REC': 1.0, 'YDS': 7.0},
{'first_name': u'Mike', 'last_name': u'Walsh','team': u'TeamTwo', 'AVG': 12.0, 'REC': 1.0, 'YDS': 12.0},
{'first_name': u'Steve', 'last_name': u'Mottola','team': u'TeamTwo', 'AVG': 18.0, 'REC': 2.0, 'YDS': 36.0},
{'first_name': u'Craig', 'last_name': u'Schubert','team': u'TeamOne', 'AVG': 23.5, 'REC': 2.0, 'TD': 1.0, 'YDS': 47.0}]  

I tried with nested for loops but kept getting an error that the "dict is unhashable." What is the best solution for this data structure?

+2  A: 
temp = {}
for rec in orig_list:
    temp.setdefault((rec['first_name'], rec['last_name'], rec['team']), {}).setdefault(rec['display_name'], rec['value'])

persons = []
for key, person in temp.iteritems():
    person.update(dict(zip(('first_name', 'last_name', 'team'), key)))
    persons.append(person)
eumiro
Thank you eumiro. This does give me the output I want. I will read up on update and setdefault to understand how it all works.
simi
What's wrong with `collections.defaultdict`?
S.Lott
A: 

Here is what I got using collections.defaultdict:

from collections import defaultdict
j = defaultdict(dict)
for player in origlist:
 j[(player['first_name'],player['last_name'],player['team'])].update({player['display_name']: player['value']})

This gives me the following output for j.items():

[((u'Mike', u'Walsh', u'TeamTwo'), {u'AVG': 12.0, u'REC': 1.0, u'YDS': 12.0}),
 ((u'Jake', u'Sarson', u'TeamOne'), {u'AVG': 7.0, u'REC': 1.0, u'YDS': 7.0}),
 ((u'Steve', u'Mottola', u'TeamTwo'),
  {u'AVG': 18.0, u'REC': 2.0, u'YDS': 36.0}),
 ((u'Craig', u'Schubert', u'TeamOne'),
  {u'AVG': 23.5, u'REC': 2.0, u'TD': 1.0, u'YDS': 47.0})]

From the j.items() then I go build the final list:

nl0 = []
for k,v in j.items():
    o = {'first_name': k[0], 'last_name': k[1], 'team': k[2]}
    o.update(v)
    nl0.append(o)
    o = {}

And the result is what I need:

[{u'AVG': 12.0,
  u'REC': 1.0,
  u'YDS': 12.0,
  'first_name': u'Mike',
  'last_name': u'Walsh',
  'team': u'TeamTwo'},
 {u'AVG': 7.0,
  u'REC': 1.0,
  u'YDS': 7.0,
  'first_name': u'Jake',
  'last_name': u'Sarson',
  'team': u'TeamOne'},
 {u'AVG': 18.0,
  u'REC': 2.0,
  u'YDS': 36.0,
  'first_name': u'Steve',
  'last_name': u'Mottola',
  'team': u'TeamTwo'},
 {u'AVG': 23.5,
  u'REC': 2.0,
  u'TD': 1.0,
  u'YDS': 47.0,
  'first_name': u'Craig',
  'last_name': u'Schubert',
  'team': u'TeamOne'}]

Is this a good example of how to use collections.defaultdict?

simi