2015-02-26 3 views
0

Я построить словарь из листа первенствовать и в конечном итоге что-то вроде:Как быстро получить список ключей от Dict

d = {('a','b','c'): val1, ('a','d'): val2} 

кортежей, которые я использую в качестве клавиши содержат несколько значений, цель для получения списка этих значений, которые встречаются более определенного количества раз.

Я пробовал два решения, оба из которых занимают слишком много времени.

Покушение 1, простой список постижение фильтр:

keyList = [] 
for k in d.keys(): 
    keyList.extend(list(k)) 

# The script makes it to here before hanging 

commonkeylist = [key for key in keyList if keyList.count(key) > 5] 

Это займет навсегда, так как list.count() проходит по меньшей мере на каждой итерации понимания.

Попытка 2, создать счета словарь

keyList = [] 
keydict = {} 
for k in d.keys(): 
    keyList.extend(list(k)) 

# The script makes it to here before hanging 

for k in keyList: 
    if k in keydict.keys(): 
     keydict[k] += 1 
    else: 
     keydict[k] = 1 

commonkeylist = [k for k in keyList if keydict[k] > 50] 

я думал, что это будет быстрее, так как мы пересекаем только все KeyList горсть раз, но до сих пор висит сценарий.

Какие еще меры я могу предпринять для повышения эффективности этой операции?

+0

не использовать .keys, то есть создать список. Вам также не нужно вызывать список по k –

ответ

3

Используйте collections.Counter() и выражение генератора:

from collections import Counter 

counts = Counter(item for key in d for item in key) 
commonkkeylist = [item for item, count in counts.most_common() if count > 50] 

где итерация по словарю непосредственно дает ключи без создания посредническую объекта списка.

Demo с меньшим кол фильтра:

>>> from collections import Counter 
>>> d = {('a','b','c'): 'val1', ('a','d'): 'val2'} 
>>> counts = Counter(item for key in d for item in key) 
>>> counts 
Counter({'a': 2, 'c': 1, 'b': 1, 'd': 1}) 
>>> [item for item, count in counts.most_common() if count > 1] 
['a'] 
+0

Зачем использовать 'iterkeys()' вообще? Итерация по диктору уже итерации по клавишам. – stranac

+1

@stranac: Смотрите, вот что 2 часа в пабе делает с вами. Не пейте и не пишите. –

+0

Бегает как сон, но я не думаю, что могу ответить на этот ответ из-за моральных исключений с состоянием автора :) – wnnmaw

0

Я думал, что это будет быстрее, так как мы пересекаем только все KeyList горсть раз, но до сих пор висит сценарий.

Это потому, что вы все еще выполняете поиск по O (n). Заменить это:

for k in keyList: 
    if k in keydict.keys(): 

с этим:

for k in keyList: 
    if k in keydict: 

и посмотреть, поможет ли ваша вторая попытка выполнить лучше.

Смежные вопросы