質問

彼は、最もPython的な解決策を探す興味深い問題です。マッピングのリスト {'id':id、 'url':url} があるとします。リスト内の一部の id が重複しています。重複するものをすべて削除して、新しいリストを作成します。私は次の機能を思いつきました:

def unique_mapping(map):
    d = {}
    for res in map:
        d[res['id']] = res['url']

    return [{'id': id, 'url': d[id]} for id in d]

かなり効率的だと思います。しかし、「もっとPythonic」なのはありますか?方法?またはおそらくより効率的な方法ですか?

役に立ちましたか?

解決

ジェネレーター式を使用して最初の辞書を作成し、別のマッピングを作成する必要性をなくすために、サンプルをわずかに書き直すことができます。古いものを再利用するだけです:

def unique_mapping(mappings):
    return dict((m['id'], m) for m in mappings).values()

これはワンライナーとして出てきましたが、それでもかなり読みやすいと思います。

元のソリューションと私のソリューションを使用する際には、次の2つの点に注意する必要があります。

  • アイテムは常に元の順序で返されるとは限りません
  • 後のエントリは同じidを持つ以前のエントリを上書きします

気にしない場合は、上記の解決策をお勧めします。それ以外の場合、この関数は順序を保存し、最初に遭遇したIDを優先的に処理します。

def unique_mapping(mappings):
    addedIds = set()
    for m in mappings:
        mId = m['id']
        if mId not in addedIds:
            addedIds.add(mId)
            yield m

ジェネレーターではなくリストが必要な場合は、 list(unique_mappings(mappings))で呼び出す必要があります。

他のヒント

改善できることがいくつかあります。

  • 2つのループを実行しています。1つは元の辞書に対して実行し、もう1つは結果の辞書に対して実行します。代わりに1ステップで結果を作成できます。

  • リスト全体を事前に作成しないように、ジェネレータを使用するように変更できます。 (必要な場合はlist(unique_mapping(items))を使用して完全なリストに変換します)

  • 重複をチェックするだけで値を保存する必要はありません。代わりにセットを使用できます。

  • 元の要素を返すのではなく、各要素の辞書を再作成しています。これは実際には必要な場合があります(たとえば、それらを変更し、オリジナルに触れたくない場合)が、そうでない場合は、すでに作成された辞書を使用する方が効率的です。

実装は次のとおりです。

def unique_mapping(items):
    s = set()
    for res in items:
        if res['id'] not in s:
            yield res
            s.add(res['id'])

これはもっと簡単にできると思います。辞書は重複キーを許容しません。マッピングのリストをマッピングの辞書にします。これにより重複が削除されます。

>>> someListOfDicts= [
    {'url': 'http://a', 'id': 'a'}, 
    {'url': 'http://b', 'id': 'b'}, 
    {'url': 'http://c', 'id': 'a'}]

>>> dict( [(x['id'],x) for x in someListOfDicts ] ).values()

[{'url': 'http://c', 'id': 'a'}, {'url': 'http://b', 'id': 'b'}]
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top