如何在Python中反转一个值为列表的字典?

20

我想编写一个函数,它接收一个字典作为输入参数,并返回该输入字典的反转版本,其中原始字典的值用作返回字典的键,原始字典的键用作返回字典的值,如下所述:

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
问题在于你不能使用任何对象作为字典的键 -- 这些对象必须是不可变的,以便它们的哈希值在添加到字典后不会改变。在你的情况下,列表是可变的,因此不能用作键。你可以将它们转换为元组来代替。 - Frédéric Hamidi
2
欢迎来到StackExchange!更深入地思考这个问题可能会有所帮助。例如,为什么'Accurate': ['exact', 'precise']会变成'precise': ['accurate', 'exact']而不是'exact': ['accurate', 'precise']?就您的错误信息而言,列表不能作为字典键,但我认为更大的问题是需要澄清您的任务。 - Daniel Standage
另外,字典无法排序。 - Farhan.K
1
@FrédéricHamidi 他正在尝试使用字符串作为键,而不是列表。只是他做得不对。 - zondo
对我来说很清楚。值的内容成为键,而键被添加到值中,因此{'a': ['b', 'c']}变成了{'b': ['a'], 'c': ['a']}。@DanielStandage,@SteinarLima - Vincent Savard
啊,我明白了@DanielStandage - 就像我说的,有时候我可能会有点慢.. 嘿嘿 :-) - Steinar Lima
5个回答

16
你可以简单地像这样做:
newdict = {}
for key, value in olddict.items():
    for string in value:
        newdict.setdefault(string, []).append(key)

无论何时有机会,一定要使用字典推导式 :) - DaveBensonPhillips
你能举个例子吗?我就是想不出一个可行的。 - zondo
哦,糟糕 - 我以为你已经这样做了,我太傻了。我并不是想居高临下,但我意识到我确实是这样表现的,道歉。 - DaveBensonPhillips
坚果。我希望你能想出一个;)我删除了列表推导式,因为它真的不应该被使用。 - zondo
尽管如此,我仍然很感激 :) - DaveBensonPhillips

5

我会使用默认字典来交换键/值:

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)

1
使用字典推导式!
>>> 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
这不是问题所问的。它要求当值为列表时的情况。 - Durga Swaroop

1

为了热爱函数式编程,这里有一个有趣的方式:

from itertools import product
from more_itertools import map_reduce, flatten

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

value_key_pairs = flatten(product(v,(k,)) for k,v in olddict.items())
out = map_reduce(value_key_pairs, lambda k:k[0].lower(), lambda k:k[1].lower())

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


-2

如何反转一个字典:

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

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

这个答案最适合我的问题(以及标准的键值字典)。谢谢 ;) - Dr. Younes Henni
如果字典的值是列表(就像问题中一样),这种方法无法正常工作。 - mkrieger1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接