Thomas Jerkson
Thomas Jerkson

Reputation: 229

Python quick trick to arrange list

again. I have this:

[
 [{'location': u'Austria',      u'number': 33},
 {'location':  u'Albania',      u'number': 29},
 {'location':  u'Afghanistan',  u'number': 666}],

 [{'location': u'Austria',      u'items': 6},
 {'location':  u'Albania',      u'items':  1},
 {'location':  u'Afghanistan'}, u'items':  0],

 [{'location': u'Austria',      u'loss': 1.0},
 {'location':  u'Albania',      u'loss': 2.0},
 {'location':  u'Afghanistan',  u'loss': 6.6}]
]

And I've tried generate list like this:

[
 [u'Austria',     33,  6, 1.00], 
 [u'Albania',     29,  1, 2.00], 
 [u'Afghanistan', 666, 0, 6.60]
]

I've tried this:

country = [i['location'] for i in data[0]]
number =  [i['number'] for i in data[0]]
items =   [i['items'] for i in data[1]]
loss =    [i['loss'] for i in data[2]]

then I zip this:

for i in range(0,len(country)):
        l.append([name[i], number[i], items[i], loss[i]])

And its work, but: 1) its ugly (for me) 2) its not 'one-size-fits-all'

In other time I may have only:

[
 [{'location': u'Austria',      u'number': 33},
 {'location':  u'Albania',      u'number': 29},
 {'location':  u'Afghanistan',  u'number': 666}],

 [{'location': u'Austria',      u'loss': 1.0},
 {'location':  u'Albania',      u'loss': 2.0},
 {'location':  u'Afghanistan',  u'loss': 6.6}]
]

And my code will fail (out of index), other time I may have more list in list, etc. How do this fine?

Upvotes: 1

Views: 67

Answers (2)

nigel222
nigel222

Reputation: 8212

What about this?

from collections import OrderedDict

od=OrderedDict()
for dl in data:
  for d in dl:    
    loc = d['location']
    od.setdefault(loc,{}).update(**d)

for k in od: print od[k]

{u'loss': 1.0, 'location': u'Austria', u'number': 33}
{u'loss': 2.0, 'location': u'Albania', u'number': 29} 
{u'loss': 6.6, 'location': u'Afghanistan', u'number': 666}

It will accumulate any set of directory keys into a single directory, and preserve the original ordering of locations.

From here if you want a list-of-lists with any fields in any order:

fields=['location', 'loss', 'number'] 
lofl = [[ oo[k][x] for x in fields] for k in oo ]

>>> lofl
[[u'Austria', 1.0, 33], [u'Albania', 2.0, 29], [u'Afghanistan', 6.6, 666]]

Upvotes: 0

mgilson
mgilson

Reputation: 310079

First, I'd transpose it so that all Australia are together:

data_t = zip(*data)

Then I'd accumulate the rows by pulling off the first non-'location' key in the sub-dict (since that seems to be the field you're looking for).

rows = []
for country_dat in data_t:
    country = country_dat[0]['location']
    row = [country]
    rows.append(row)
    for dct in country_dat:
        key = next(k for k in dct if k != 'location')
        row.append(dct[key])

Upvotes: 6

Related Questions