2017-12-27 21 views
0

私はこのような形でJSONから生成辞書のいくつかのmilionsのリストを持っている:Python - 複雑なオブジェクトの順序付きリストから重複を削除しますか?

{ 
    "_id":XXX, 
    "some_other":"fields", 
    ... 
} 

リストは、しかし、重複_idとdisctionariesがある_idキーで安全ソートする必要があります。実際にはリストのサイズと比較して重複はほとんどありません(最大10-100程度)。私は最初に(または最後に、それが決定論的である限り重要ではない)各複製の辞書を取ってほしい_id。 JavaScriptで私は以下を使用したいと思います:

list.sort((a,b)=>a._id>b._id?1:(a._id<b._id?-1:0)) 
    .filter((ent,i,arr)=>i==0||ent!=arr[i-1]) 

しかし、私はフィルタのpythonの変形は、アイテムのインデックスにアクセスできないと思いますか? Pythonでこのようなことを達成するための同様の短い方法はありますか?私はsorted(...)という機能を使って、私が望む方法でこのリストを並べ替えることができますが、重複しているものをフィルタリングする方法はまだ分かりません。

+0

あなたはsorted'と 'filter''を見てきましたか?Pythonは 'map'、' filter'、 'reduce'構文を持っています。' lambda args: 'を使って、Pythonの(無意味で)匿名の関数構文と同等の式を書くことができます。フィルタリング/マッピングのために、頻繁にリスト内包(および関連するコンストラクト、例えば 'dict'内包、' set'内包、さらにはジェネレータ式)はより慣用的と見なされます。 –

答えて

2

(これは常に各_idための最後に出現し続けます)重複を削除するために辞書を使用します。次に

d = {i['_id']: i for i in your_list} 

をソート_idによってその値:

list(sorted(d.values(), key=lambda i: i['_id'])) 
2

慣用的な方法、Pythonで、次のようになります。ビルトインのpython sorted

import itertools 
import operator 

get_id = operator.itemgetter('_id') #factory function: lambda x:x['_id'] 
grouped = itertools.groupby(sorted(json_data, key=get_id), get_id) 

result = [next(g) for k,g in grouped] 

注意、安定ソートされ、 timsortという適応型マージソートを使用します。

itertoolsは、さまざまな遅延イテレータを効率的に実装する非常に便利なモジュールです。 groupbyはグループイテレータです:

# [k for k, g in groupby('AAAABBBCCDAABBB')] --> A B C D A B 
# [list(g) for k, g in groupby('AAAABBBCCD')] --> AAAA BBB CC D     

あなたはpythonの無名関数と(Pythonで、「条件式」)三項演算子を使って、あなたのjavascriptの音訳を作成することができます。 key=str.lower

キー各リスト要素から 比較キーを抽出するために使用される1つの引数の関数を指定:注は、コンパレータ機能を使用していないPythonのsorted機能は、それがkey-based functionを使用しています。 のデフォルト値はNoneです(要素を直接比較してください)。パイソン2において

、JavaScriptバージョンと同様に機能cmp引数は依然として利用可能である(例えば、-1を返す関数、1、または0)

cmpは廃止され、最終的にはPython 3で除去しkeyが好ましい。使用

1

sortedfilter、およびmap

d = [ 
    { 
     "_id": 3, 
     "some_other": "a" 
    }, 
    { 
     "_id": 1, 
     "some_other": "b" 
    }, 
    { 
     "_id": 2, 
     "some_other": "c" 
    }, 
    { 
     "_id": 2, 
     "some_other": "d" 
    } 
] 

sorted_d = sorted(d, key=lambda x: x['_id']) 
map(
    lambda y: y[1], 
    filter(
     lambda x: True if x[0]==0 else sorted_d[x[0]]["_id"] != sorted_d[x[0]-1]["_id"], 
     enumerate(sorted_d) 
    ) 
) 

出力:

[{'_id': 1, 'some_other': 'b'}, 
{'_id': 2, 'some_other': 'c'}, 
{'_id': 3, 'some_other': 'a'}] 
関連する問題