2015-11-26 4 views
-1

У меня возникла следующая проблема. У меня есть следующее Dict с уникальными ключами и множество значений:Словарь с отсортированными уникальными значениями

dic = {'Hipster': ['John', 'Thomas','Peter'],'Geek': ['Irvin'], 'Funny': 
['Lucas','Thomas'],'Clever': ['Peter']} 

Я хочу создать новый словарь, такие как: я) Она начинается с ключом, который имеет наибольшее количество значений, б) значения, связанные с ключи уникальны, т.е. Они не связаны с предыдущим ключом. Выходной сигнал будет:

dic2 = {'Hipster': ['John', 'Thomas','Peter'],'Geek': ['Irvin'],'Funny': 
['Lucas']} 

Более формально, это как преобразование следующего словаря:

Initial_dic = {key1:[Values1],key2:[Values2],key3:[Values3],....] 
Final_dic = {key1:[Values1],key2:[Values2-Values1],key3:[Value3-Values2-Values1],....] 

Заранее спасибо за ваши ответы!

+1

Stackoverflow не является услугой кодирования; покажите нам, что вы пробовали. –

+0

Клавиши в словаре неупорядочены. Они не могут начать с определенного ключа. – interjay

+0

@interjay Вы можете заказать свой словарь, например, используя коллекции import OrderedDict. Вы получите объект типа словаря. –

ответ

1

Вам необходимо сделать это за два прохода; значения сортировки и выброса:

def order_and_strip(d): 
    sorted_items = sorted(d.items(), key=lambda kv: len(kv[-1]), reverse=True) 
    seen = set() 
    for key, value in sorted_items: 
     yield key, list(set(value) - seen) 
     seen.update(value) 

Я предполагаю, что порядок в выходных списках не важен. Если использовать список понимание:

yield key, [v for v in value if v not in seen] 

выше является генератор, который дает пар ключ-значение в отсортированном порядке. Вы можете поместить их в OrderedDict(), если вы хотите, чтобы относиться к этому как словарь с определенным ключом заказа:

result = OrderedDict(order_and_strip(dic)) 
1

Прежде всего словарей не имеют отчетливый порядок. вы должны подумать о более подходящей структуре данных для своей проблемы. Если вы хотите, чтобы наклеить на Dict ты по крайней мере, следует использовать OrderedDict (https://docs.python.org/2/library/collections.html#collections.OrderedDict)

Тем не менее, вы можете попробовать это:

import collections 

input_dic = {'Hipster': ['John', 'Thomas','Peter'],'Geek': ['Irvin'], 'Funny': 
['Lucas','Thomas'],'Clever': ['Peter']} 



def do_courious_dict_action(dic): 
    o_dic = collections.OrderedDict(sorted(dic.iteritems(),key=lambda x: len(x[1]), reverse=True)) 
    tmp_dic = {} 
    for item in o_dic.iteritems(): 
     temp_list = item[1] 
     for i in range(0,o_dic.keys().index(item[0])): 
      temp_list = [x for x in temp_list if x not in o_dic.items()[i][1]] 
     tmp_dic[item[0]] = temp_list 



    tmp2_dic = {k:v for k, v in tmp_dic.iteritems() if len(v)>0} 

    new_o_dic = collections.OrderedDict() 

    for ordered_key in o_dic.keys(): 
     if ordered_key in tmp2_dic: 
      new_o_dic[ordered_key] = tmp2_dic[ordered_key] 

    return new_o_dic 

print do_courious_dict_action(input_dic) 

Это почти производят то, что вы хотите, кроме арматуры переключается " Funny 'и' Geek ', поскольку в начале игры было 2 записи. Но, может быть, это дает вам подсказку, в каком направлении вы должны смотреть в

Edit: Хорошо Решение Martijn Питерс с генераторами гораздо более вещий ;-)

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