2

次のリストがあるとします

l = [ {'id':1, 's':1.0 }, {'id':3, 's': 0.6}, {'id':1, 's': 1.5} ]

'id'値に基づいて、値が重複している要素を削除したいと思い's'ます。
前の例では、最初の要素と 3 番目の要素の両方が破棄されているため、最初の要素を破棄したいと思い'id'==1ます。l[0]['s'] < l[2]['s']l[0]

したがって、私が期待する出力は次のとおりです(出力リスト内の要素の順序は気にしません)

[ {'id':1, 's':1.5}, {'id':3, 's':0.6} ]
4

6 に答える 6

5

マッピングを使用して ID とそのスコアを追跡します。

from collections import defaultdict

id_to_scores = defaultdict(list)

for entry in l:
    id_to_scores[entry['id']].append(entry['s'])

output = [{'id': k, 's': max(v)} for k, v in id_to_scores.iteritems()]

.items()Python 3 を使用している場合は、代わりに使用してください。

結果 ( adictには決まった順序がないため、順序が変更されました):

>>> [{'id': k, 's': max(v)} for k, v in id_to_scores.iteritems()]
[{'s': 1.5, 'id': 1}, {'s': 0.6, 'id': 3}]

これにより、辞書が再構築されます。他のキーが関係している場合はid、スコアだけでなく、それぞれの辞書全体を保存する必要があります。

per_id = defaultdict(list)

for entry in l:
    per_id[entry['id']].append(entry)

output = [max(v, key=lambda d: d['s']) for v in per_id.itervalues()]
于 2013-05-01T11:37:11.140 に答える
4

使用collections.defaultdict:

In [58]: dic=defaultdict(dict)

In [59]: for x in lis:
    idx=x['id']
    if dic[idx].get('s',float('-inf')) < x ['s']:
        dic[idx]=x
   ....:         

In [60]: dic.values()
Out[60]: [{'id': 1, 's': 1.5}, {'id': 3, 's': 0.6}]

シンプルな使用dict

In [71]: dic={}

In [72]: for x in lis:
    idx=x['id']
    if dic.get(idx, {'s': float('-inf')}) ['s'] < x['s']:
        dic[idx]=x
   ....:         

In [73]: dic.values()
Out[73]: [{'id': 1, 's': 1.5}, {'id': 3, 's': 0.6}]
于 2013-05-01T11:39:25.900 に答える
3

これが itertools のgroupbyを使用した私の解決策です。

>>> l = [ {'id':1, 's':1.0 }, {'id':3, 's': 0.6}, {'id':1, 's': 1.5} ]
>>> from itertools import groupby
>>> key = lambda dct: dct['id']
>>> l.sort(key=key)
>>> for key, group in groupby(l, key=key):
...     print max(group, key=lambda dct: dct['s'])
... 
{'s': 1.5, 'id': 1}
{'s': 0.6, 'id': 3}

Re: アシュウィニ

さまざまなソリューションを比較して、パフォーマンステストを行いました。グラフ形式の結果は次のとおりです。

ここに画像の説明を入力

ここではキーに 10 の異なる値のみを使用しまし'id'た。自分でコードを操作して、 の構成が結果にどのようにlst影響するかを確認できます。値の数をリスト内の項目数の半分に変更すると、idAshwini が明確な勝者となり、残りのメンバーがまとめられます。

ここに画像の説明を入力

ログ対ログ グラフのO(n)ソリューションとソリューションを比較すると、次のようになります。O(n*log(n))

ここに画像の説明を入力

そのため、big O の議論に関してどのような結論を導き出すかはよくわかりません。

于 2013-05-01T11:38:27.240 に答える
0
>>> L = [ {'id':1, 's':1.0 }, {'id':3, 's': 0.6}, {'id':1, 's': 1.5} ]
>>> res = {}
>>> for d in L:
        id_ = d['id']
        res[id_] = max(res.get(id_, {}), d, key=lambda x: x.get('s', float('-inf')))


>>> res.values()
[{'s': 1.5, 'id': 1}, {'s': 0.6, 'id': 3}]
于 2013-05-01T11:38:13.460 に答える
0

降順sで並べ替え、各idについて最高のsものを最初に並べます。次に、 の最初の出現のみを選択しidます。

seen = set()
output = [d for d in sorted(l, key=lambda d: d['s'], reverse=True)
          if d['id'] not in seen and not seen.add(d['id'])]

入力に触れることを犠牲にして追加のスペースを避けるために、最初にその場でソートすることを決定することもできます。

これらすべては、時間と空間の複雑さの点で最適ではないかもしれませんが、非常にエレガントです。

于 2013-05-01T12:02:30.240 に答える
0
>>> l2={}
>>> for y in l:
        l2.setdefault(y['id'],[]).append(y['s'])
>>> l3=[{'id':k,'s':max(v)} for k,v in l2.items()]
>>> print l3

与えます:

[{'id': 1, 's': 1.5}, {'id': 3, 's': 0.6}]
于 2013-05-01T11:52:57.070 に答える