2016-03-11 5 views
11

Я хотел бы написать функцию, которая получает словарь в качестве входного аргумента и возвращает обратную ссылку словаря ввода, где значения исходного словаря используются как ключи для возвращаемого словаря, а ключи исходного словаря используются как значение для возвращенного словаря, как описано ниже:Как отменить словарь в Python?

dict = {'Accurate': ['exact', 'precise'], 
     'exact': ['precise'], 
     'astute': ['Smart', 'clever'], 
     'smart': ['clever', 'bright', 'talented']} 

в

dict = {'precise': ['accurate', 'exact'], 
     'clever': ['astute', 'smart'], 
     'talented': ['smart'], 
     'bright': ['smart'], 
     'exact': ['accurate'], 
     'smart': ['astute']} 

список значений в возвращаемом словаре должны быть отсортированы в порядке возрастания. Капитализация не имеет значения. Это означает, что все слова должны быть преобразованы в строчные буквы. Например, слово «Accurate» заглавное в оригинальном словаре, но в возвращенном словаре оно написано со всеми строчными буквами.

#My code is: 
from collections import defaultdict 
def reverse_dictionary(input_dict): 
    d = defaultdict(list) 
    for v,k in input_dict.items(): 
     d[k].append(v) 
     return d 

Но он возвращает эту ошибку, хотя:

Error in evaluating function: 
TypeError at line 6 
unhashable type: 'list' 
+3

Проблема заключается в том, что вы не можете использовать какой-либо объект в качестве ключа - эти объекты должны быть неизменными, поэтому их хэш va lue не изменяется после добавления в словарь. В вашем случае списки изменяемы, поэтому их нельзя использовать в качестве ключей. Вместо этого вы можете преобразовать их в кортежи. –

+2

Добро пожаловать в StackExchange! Возможно, было бы полезно подумать над этой проблемой. Например, почему бы «Точная»: [«точно», «точно»] 'становиться« точным »: ['exact', 'exact']' вместо ''exact': ['exact', 'exact «] '? Что касается вашего сообщения об ошибке, список не может быть вашей ключевой фразой, но я думаю, что большая проблема заключается в том, что задача должна быть уточнена. –

+0

Кроме того, словари не могут быть отсортированы. –

ответ

5

Вы можете сделать это очень просто l ike:

newdict = {} 
for key, value in olddict.items(): 
    for string in value: 
     newdict.setdefault(string, []).append(key) 
+0

Всегда, всегда, всегда пользуйтесь соображениями при возникновении случайности :) – DaveBensonPhillips

+0

Можете ли вы привести пример? Я просто не мог думать о том, что будет работать. – zondo

+0

Ой, ох - Я думал, это то, что ты сделал, я был глупым.Я не старался быть снисходительным, но я понимаю, что это именно то, как я сошел, извинения – DaveBensonPhillips

4

Я бы начать путем замены ключей/значений с помощью Dict по умолчанию:

output_dict = defaultdict(list) 
for key, values in input_dict.items(): 
    for value in values: 
     output_dict[value.lower()].append(key.lower()) 

И, наконец, сортировка:

for key, values in output_dict.items(): 
    output_dict[key] = sorted(values) 
4

Используйте понимание ди-джея!

>>> evil_petting_zoo = {'bear':3, 'crocodile':1,'kangaroo':2,'goat':0} 
>>> evil_petting_zoo.items() 

dict_items([('bear', 3), ('crocodile', 1), ('kangaroo', 2), ('goat', 0)]) 

>>> {i[1]:i[0] for i in evil_petting_zoo.items()} 

{3: 'bear', 1: 'crocodile', 2: 'kangaroo', 0: 'goat'} 

TL; DR:

{i[1]:i[0] for i in myDictionary.items()} 
1

Как отменить Dict:

def reverse(org): 
    return {v: k for k, v in org.items()} 

print(reverse({1: 'a', 2: 'b'})) 
# {'a': 1, 'b': 2} 
+0

этот ответ лучше всего подходит для моей проблемы (и для стандартного ключа: значение dict). Благодаря ;) –

0

это ответ, без использования каких-либо модулей:

def reverse_dictionary(input_dict): 
    out = {} 
    for v in input_dict.values(): 
     for value in v: 
      if value not in out: 
       out[value.lower()] = [] 
    for i in input_dict: 
     for j in out: 
      if j in map (lambda x : x.lower(),input_dict[i]): 
       out[j].append(i.lower()) 
       out[j].sort() 
    return out 
Смежные вопросы