2

私は現在、AppEngine アプリに取り組んでおり、属性の 1 つに基づいてグループに分割したいデータストアからのオブジェクトのリストを持っています。これに対する解決策はありますが、これを行うためのより良い方法を誰かが知っているかどうかを確認したかったのです。

これは私が現時点で持っているコードです:

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)

しかし、より良いのはdefaultdictです:

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 に答える