Проблема с вызовом dictionary2 = set(dictionary1.values())
заключается в том, что dictionary1.values()
просто возвращает список всех значений в dictionary1. Каждое из этих значений само является списком (например, ['frog', 'frog']
является одним элементом списка .values()
). Вызов set()
в многомерном списке (что и происходит здесь) приводит к TypeError: unhashable type: 'list'
, потому что set()
принимает только списки неизменяемых (хэшируемых) объектов, но списки являются изменяемыми. См. этот вопрос для более.
Кроме того, вызов set()
на dictionary1.values()
действительно просто уменьшит список значений, так что список животных не будет повторяться. Другими словами, set([('mouse', 'mouse'), ('mouse', 'mouse')])
приводит к {('mouse', 'mouse')}
, а не {('mouse'), ('mouse')}
, что, я считаю, ближе к тому, что вы ищете. (Примечание: здесь используются кортежи, поскольку они неизменны)
То, что вы хотите сделать, это вызвать set()
(а затем привести обратно к списку с list()
) на каждое значение в dictionary1.values()
и сделать это внутри нового словаря. Это можно сделать с помощью словарного понимания (аналогично более распространенному списковому пониманию).
Вот как это можно сделать:
dictionary1 = {'cat': ['frog', 'frog'] , 'dog': ['deer', 'deer', 'deer', 'goat'], 'bat': ['apes', 'mice', 'mice'] }
dictionary2 = {key: list(set(value)) for key, value in dictionary1.items()}
Приведенный выше код приводит к:
dictionary1 #=> {'cat': ['frog', 'frog'] , 'dog': ['deer', 'deer', 'deer', 'goat'], 'bat': ['apes', 'mice', 'mice'] }
dictionary2 #=> {'cat': ['frog'], 'dog': ['goat', 'deer'], 'bat': ['apes', 'mice']}
по желанию.