1

リストがあります:

import numpy as np


A=[(2, 2, 0), (1, 5, 0), (6, 8, 0), (2, 2, 2) ]

ax=np.asarray([row[0] for row in A])
ay=np.asarray([row[1] for row in A])
az=np.asarray([row[2] for row in A])

print (ax,ay,az)

axとayを比較したいと思います。ax==ayが(2、2、0)と(2、2、2)のように等しいペアを見つけたら、ペアを1回保持しますが、az値を追加します。したがって、この例では、新しい指名手配リストBは次のようになります。

B=[(2, 2, 2), (1, 5, 0), (6, 8, 0)]

本当に巨大なリストでも効率的なコードがあればいいのにと思います。

4

2 に答える 2

2

辞書(またはcollections.Counter)は、numpy配列よりも現在のアイテムをチェックする方が高速です。

したがって、出力順序が重要でない場合:

from collections import Counter
c = Counter()
A = [(2, 2, 0), (1, 5, 0), (6, 8, 0), (2, 2, 2) ]
for a in A:
    c[a[:2]] += a[2]
B = [list(k) + [v] for k,v in c.iteritems()]

B今です:

[[1, 5, 0],  [6, 8, 0], [2, 2, 2]]
于 2012-07-27T11:07:54.717 に答える
1

順序が重要でない場合

from collections import defaultdict

dd = defaultdict(int)
for x, y, z in A:
    dd[(x,y)] += z
res = [k + (v,) for k, v in dd.iteritems()]
# [(1, 5, 0), (6, 8, 0), (2, 2, 2)]

注文が重要な場合

from operator import itemgetter

d = {}
for idx, (x, y, z) in enumerate(A):
    pos, freq = d.get((x,y), (0,0))
    d[(x,y)] = min(pos, idx), freq + z

res = sorted((k + (v[1],) for k, v in d.iteritems()), key=itemgetter(1, 1))
# [(2, 2, 2), (1, 5, 0), (6, 8, 0)]
于 2012-07-27T12:22:06.287 に答える