2

我目前正在开发一个 AppEngine 应用程序,并且有一个来自数据存储区的对象列表,我想根据它们的一个属性将它们分成组。我有一个解决方案,但我想检查是否有人知道更好的方法来做到这一点。

这是我目前拥有的代码:

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)

欢迎任何想法!

4

3 回答 3

3

你可以有一个从状态到功能的字典,如下所示:

d= {"new":new_reports.append,
    "read":read_reports.append,
    "accepted":accepted_reports.append,
    "deined":denied_reports.append,
    "resubmitted":resubmitted_reports.append
}

for report in reports:
     d[report.status](report)
于 2013-10-06T16:31:09.003 回答
2

字典会更好,而不是所有的局部变量:

reports_by_status = {'new': [],
     'read': [],
     'accepted': [],
     'deined': [],    # denied?
     'resubmitted': []}

for report in reports:
    d[report.status].append(report)

但是你打错字了!通过使用status变量中的任何数据来分配类别可能会很好地防止这种情况:

reports_by_status = {}
for report in reports:
    if report.status not in reports_by_status:
        reports_by_status[status] = []
    reports_by_status[status].append(report)

这是一种常见的模式,所以我们有一些方法可以让它变得更好:

reports_by_status = {}
for report in reports:
    reports_by_status.set_default(report.status, []).append(report)

但更好的是默认字典:

from collections import defaultdict
by_status = defaultdict(list)
for report in reports:
    by_status[report].append(report)

itertools.groupby很好,它封装了分类动作:

from itertools import groupby
by_status = {}
for category, group in groupby(reports, lambda x: x.status):
    by_status[category] = list(group)

但是现在我们的循环看起来是map()-ish,所以让我们使用列表推导:

from itertools import groupby
dict([(k:list(v)) for k, v in groupby(reports, lambda x: x.status)])

然后记住我们在 Python 2.7 中,所以我们也有字典推导:

from itertools import groupby
{k:list(v) for k, v in groupby(reports, lambda x: x.status)}

或到目前为止我最喜欢的,

from itertools import groupby
from operator import attrgetter
{k:list(v) for k, v in groupby(reports, attrgetter('status'))}
于 2013-10-06T17:36:58.923 回答
1

字典呢:

dct = {"new":new_reports, "read":read_reports, "accepted":accepted_reports, "denied":denied_reports, "resubmitted":resubmitted_reports}
for report in reports:
    dct[report.status].append(report)

或者,如果有可能 areport.status不在字典中,您可以添加一个 try/except 块:

dct = {"new":new_reports, "read":read_reports,"accepted":accepted_reports, "denied":denied_reports, "resubmitted":resubmitted_reports}
for report in reports:
    try:
        dct[report.status].append(report)
    except KeyError:
        continue
于 2013-10-06T16:31:20.637 回答