2017-08-09 15 views
0

私はリスト1の外OrderedDictを作るための最速の方法は何かリストlist1 = [['colour','red'],['colour','blue],['shape','rect'],['shape','square']]のpython:最初の要素による注文dictのグループにリストのリスト

のリストを持っていますか?

{colour:['red','blue'],shape:['rect','square']} 

これまでのところ、私はLIST1を通じてマップと各内側のリストのインデックス0にユニークな要素を抽出し、list2のようにそれを返すことができました。

list1とlist2を介してマップすることができ、maching要素が見つかった場合、list1の各内側リストからインデックス1の要素を取得しますが、正しいアプローチ/高速アプローチであるかどうかはわかりません。

お願いします。

答えて

0

二つのアプローチ、あなたの入力に応じて:

オプション1:あなたの例のように、一致するすべてのキーが連続している場合は、グループ彼らにitertools.groupbyを使用することができ、(あなたは常に一緒に、すべてのcolours参照します)。

from collections import OrderedDict 
from itertools import groupby 
from operator import itemgetter 

list1 = [['colour','red'],['colour','blue],['shape','rect'],['shape','square']] 
dict1 = OrderedDict((k, [v for _, v in grp]) for k, grp in groupby(list1, itemgetter(0))) 

それは繰り返しキーが見れるたびにそれらを見ずに一度だけdictの各キーを書き込みますが、それはキーによって順序付けされた入力に依存しているので、これは、少なくとも理論的には、最速のアプローチです。

オプション2:defaultdict(list)として不足しているキーをご覧の上、同じ動作でOrderedDictを作るために__missing__特別なメソッドを使用します(悲しいことに、二つのタイプに互換性がないので、あなたは、両方から継承するクラスを作ることができないと引き換えに、

dict1 = OrderedMultidict() 
for k, v in list1: 
    dict1[k].append(v) 

このアプローチは、オプション1の順序依存性を削除します。そして、結果を蓄積するためにそれを使用

from collections import OrderedDict 

class OrderedMultidict(OrderedDict): 
    __slots__ =() # Avoid overhead of per-instance __dict__ 
    def __missing__(self, key): 
     # Missing keys are seamlessly initialized to an empty list 
     self[key] = retval = [] 
     return retval 

:、その後でそれを埋めるために、明示的なループを記述)の日それを呼びます追加のための各キーのルックアップを繰り返します(最初のルックアップだけが__missing__のPythonレベルコードを呼び出しますが、その後、最新のPython 3コードのようにOrderedDictがCレベルの場合、ルックアップはCレベルのままです)。つまり、実際には、このソリューションは現代のCPython(OrderedDictはCの組み込み型)で高速になると思われますが、繰り返し検索は理論的に各キーを正確に1回書くよりも悪いです。 Python 2およびそれ以前のPython 3では、Pythonで実装されていますが(groupbyは常にCレベルです)、groupbyが勝つ可能性は高くなりますが、両方のタイプがCアクセラレーションの場合、実際にはいくらかのオーバーヘッドがあり失われる可能性があります。

関連する問題