python - Is there a better way to split of objects by one of its attributes? -
i'm working on appengine app , have list of objects datastore want split groups based on 1 of attributes. have solution this, wanted check if knows of better way this.
this code have @ moment:
for report in reports: if report.status == 'new': new_reports.append(report) elif report.status == 'read': read_reports.append(report) elif report.status == 'accepted': accepted_reports.append(report) elif report.status == 'deined': denied_reports.append(report) elif report.status == 'resubmitted': resubmitted_reports.append(report)
any ideas welcome!
a dictionary nice instead of local variables:
reports_by_status = {'new': [], 'read': [], 'accepted': [], 'deined': [], # denied? 'resubmitted': []} report in reports: d[report.status].append(report)
but made typo! might nice prevent using whatever data in status
variable assign category:
reports_by_status = {} report in reports: if report.status not in reports_by_status: reports_by_status[status] = [] reports_by_status[status].append(report)
this common pattern, have few ways make nicer:
reports_by_status = {} report in reports: reports_by_status.set_default(report.status, []).append(report)
but nicer defaultdict:
from collections import defaultdict by_status = defaultdict(list) report in reports: by_status[report].append(report)
itertools.groupby
nice, encapsulates categorization action:
from itertools import groupby by_status = {} category, group in groupby(reports, lambda x: x.status): by_status[category] = list(group)
but our loop looking map()
-ish, let's use list comprehension:
from itertools import groupby dict([(k:list(v)) k, v in groupby(reports, lambda x: x.status)])
and remember we're in python 2.7, have dictionary comprehensions too:
from itertools import groupby {k:list(v) k, v in groupby(reports, lambda x: x.status)}
or favorite far,
from itertools import groupby operator import attrgetter {k:list(v) k, v in groupby(reports, attrgetter('status'))}
Comments
Post a Comment