2017-08-09 129 views
0

列表有序字典和組的名單上有列出list1 = [['colour','red'],['colour','blue],['shape','rect'],['shape','square']]蟒蛇:由第一要素

是什麼使一個OrderedDict出列表1的最快的方法列表?

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

到目前爲止,我已經能夠通過list1的映射,並在每個內部列表的索引0中提取獨特的元素,並返回它作爲列表2。

我可以通過list1和list2映射,如果找到maching元素,然後從list1的每個內部列表中的索引1獲取元素,但我不確定它是否是正確的方法/快速方法。

請幫忙嗎?

回答

0

兩種方法,根據您的輸入:

選項1:如果在你的榜樣,所有匹配的鑰匙是連續的(所以你總能看到所有colours在一起),你可以使用itertools.groupby將它們分組:

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:使用__missing__特殊方法作出OrderedDict具有相同的行爲上查找失蹤鍵defaultdict(list)(可悲的是,這兩種類型是不相容的,所以你不能從兩個繼承的類和收工),然後寫一個明確的循環填寫了:

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 

然後用它來積累的結果:

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

這種方法消除選項1的順序依賴,在交換添加每個鍵的重複查找(儘管只有第一個查找調用__missing__中的Python級別代碼;在此之後,如果OrderedDict與現代Python 3代碼中的C級別一樣,查找也將保持C級別)。也就是說,雖然反覆查找理論上比每次寫入關鍵字只有一次更差,但實際上我認爲這種解決方案在現代CPython上會更快(其中OrderedDict是C內置的)。在Python 2和更早版本的Python 3中,它在Python中實現(雖然groupby始終是C級別),但groupby更有可能獲勝,但是當兩種類型都是C加速時,groupby實際上會有一些額外的開銷,可能會使其丟失。