繁体   English   中英

不可用的类型:python中的'list'错误

[英]Unhashable type: 'list' error in python

我有这本字典:

final = {0: [1, 9], 1: [0, 9], 8: [16, 10], 9: [0, 1], 10: [8, 16], 16: [8, 10]}

我想将它转换为列表,所以我使用列表推导,结果如下:

myList = [[int(k)]+v for k, v in final.items()]
myList = [[0, 1, 9], [0, 1, 9], [0, 1, 9], [8, 10, 16], [8, 10, 16], [8, 10, 16]]

我还想要整个列表以及每个小列表中的元素进行排序,并从列表中删除重复项:

for i in myList:
   i.sort()

myList.sort()
list(set(myList))
print(myList)

但是,当我运行这个时,我得到错误“ Unhashable type: 'list' " 有没有其他方法来实现这个? 先感谢您!

列表是可变的; 在Python中,可变容器不可清除。 set反过来要求可清洗的项目。 您可以将列表转换为元组,这些元组是不可变容器,因此可以清除:

>>> myList = [[0, 1, 9], [0, 1, 9], [0, 1, 9], [8, 10, 16], [8, 10, 16], [8, 10, 16]]
>>> list(set(tuple(i) for i in myList))
[(8, 10, 16), (0, 1, 9)]

请注意,集合未排序,因此您可能希望创建集合进行排序:

>>> myList = [[0, 1, 9], [0, 1, 9], [0, 1, 9], [8, 10, 16], [8, 10, 16], [8, 10, 16]]
>>> sorted(set(tuple(i) for i in myList))
[(0, 1, 9), (8, 10, 16)]

如果您只是对子列表进行排序以删除欺骗,则可以使用frozensets来避免排序:

final = {0: [1, 9], 1: [0, 9], 8: [16, 10], 9: [0, 1], 10: [8, 16], 16: [8, 10]}

unique = list(map(list, {frozenset([k] + v) for k, v in final.items()}))

哪个会给你:

[[0, 1, 9], [16, 8, 10]]

您仍然可以对剩余的子列表进行排序,这些子列表仍然比首先对它们进行排序更快,然后在子列表很大和/或您有很多欺骗时删除。

unique = list(map(sorted, {frozenset([k] + v) for k, v in final.items()}))

print(unique)

如有必要,将为您提供有序输出:

[[0, 1, 9], [8, 10, 16]]

set需要一个可清除对象的列表; 也就是说,它们是不可变的 ,它们的状态在创建后不会改变。 但是, list对象是可变的 ,因为它可以更改(如sort函数所示,它会永久重新排列列表),这意味着它不可清除,因此无法使用set

解决方案是将list对象转换为tuple对象; 这些将与set因为它们是可以清洗的。 您可以通过创建一个生成器来执行此操作,然后将其传递给set:

>>> list(set(tuple(x) for x in myList))
[(0, 1, 9), (8, 10, 16)]

元组以与列表类似的方式工作,因此这不会导致现有程序出现任何问题。 如果你确实需要一个列表列表,你可以使用这样的列表解析将其转换回来:

>>> [list(x) for x in set(tuple(x) for x in myList))]
[[0, 1, 9], [8, 10, 16]]

当然。 更改:

myList = [[int(k)]+v for k, v in final.items()]

至:

myList = [tuple([int(k)]+v) for k, v in final.items()]

这会为您的字典键和值组合创建一个元组而不是列表。 元组是不可变的,可以在集合中用作值,而列表则不能。

myList是一个列表列表。 构建集合时,集合的元素必须是不可变的,才能使集合正常工作。

在这种情况下,列表是可变的(您可以appendremove项目),这对于集合是必要的,如果您可以更改列表的内容,python将无法判断您的集合是否具有重复元素。

想象一下这种情况(它不可能,但想象一下):

l1 = [1,2,3]
l2 = [1,2]
s = set([l1, l2]) #Here both lists are different
l2.append(3) #Here both lists are equal

Python应该推断你想要从集合中删除l1或l2? 哪一个? 为什么?

您可以做的一件事是使用元组而不是列表(这是列表的不可变版本)并将其转换为集合

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM