0

2 つのリスト (「IDS」と「Pay」) があります。IDS の len は 50000 で、Pay の len は 650000 です。IDS は [1,2,3,4,5,6 ... ] のような IDS のリストであり、PAY リストはすべての支払いを含むリストのリストです。 [ [1,50]、[1,100]、[1,60]、[2,50]、[2,80]、[2,50]、...]

各 ID が合計で支払った金額を知るために、次のような別の for ループ内で for ループを実行しています。

for x in IDS:
    total = 0
    for i in xrange(0,len(Pay)):
        if x == Pay[i][0]:
            total += Pay[i][1]
    print x + str(total)

しかし、これを処理するには何年もかかります!Pay を 10 個に分割しようとしましたが、それでも時間がかかりすぎます。この操作を改善するにはどうすればよいか、誰にもアイデアがありますか?

ありがとうございました!

4

4 に答える 4

3

使用できますcollections.Counter

>>> from collections import Counter
>>> pay = [ [1,50], [1,100], [1,60], [2,50], [2,80], [2,50]]
>>> c = Counter()
>>> for idx, amt in pay:
    c[idx] += amt
...     
>>> c
Counter({1: 210, 2: 180})
于 2013-09-18T14:44:17.603 に答える
2

OK、実際には、2 つの非常に長いリストがあります。どのライブラリを使用するかについて議論する代わりに、より優れたアルゴリズムについてはどうでしょうか?

Pay は (id, payment) のタプルですが、ID には当然一意の整数が含まれている必要があります (私の推測)。

ここで、リストがどこから来ているかを考えてみましょう。次の 2 つの可能性があります。

  1. ファイルから読み取る

  2. MySQL などのデータベースから

オプション 1 の場合は、代わりに次の手順を実行する必要があります。

from collections import defaultdict
totals = defaultdict(someObj_factory)
[totals[int(line.split[0])].accumulate(someObj_factory(line.split()[1]))
 for line in paymentFile]

まず、ID は Pay にあるため、ID を独立したリストにする必要はありません。

第二に、読む時間を節約できます。

第 3 に、スクリプト言語の場合、リスト内包表記は解釈時間を節約します。

第 4 に、日付やタプルなど、任意のオブジェクトを追加できるため、これは堅牢です。

オプション 2 の場合は、データベースでカウントを行います-.-

別のオプションは、これらをデータベースに挿入し、そこでカウントを行うことです。MySQL などは、この種のタスク用に設計されています。驚くほど効率的です。詳細: http://mysql-python.sourceforge.net/

于 2013-09-18T16:36:59.603 に答える
0

collections.Counterうまくいかない場合 (たとえば、別の Python バージョンを使用している場合)、支払いリストを辞書に変換しても同じ効果があります。

totals = {}
for id, amount in pay:
   totals[id] = totals.setdefault(id, 0) + amount

支払い日 [1,50,2013-09-01] のように、'2013-01-01' より後の日付のみの値を合計する必要がありますか?

次に、これを行います:

import datetime

base_date = datetime.datetime.strptime('2013-01-01', '%Y-%m-%d').date()

totals = {}
for idx, amount, pay_date in pay:
   if datetime.datetime.strptime(pay_date, '%Y-%m-%d').date() > base_date:
       totals[idx] = totals.setdefault(id, 0) + amount
于 2013-09-18T14:47:38.743 に答える