不可用的类型:python

时间:2016-03-22 20:40:59

标签: python list

我有这本词典:

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' "。还有其他方法可以实现吗?提前谢谢!

5 个答案:

答案 0 :(得分:3)

列表是可变的;在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)]

答案 1 :(得分:2)

如果您只是对子列表进行排序以删除欺骗,则可以使用 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]]

答案 2 :(得分:1)

set需要 hashable 对象的列表;也就是说,它们是 immutable ,它们的状态在创建后不会改变。 list对象是 mutable 但是,因为它可以更改(如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]]

答案 3 :(得分:1)

不确定。变化:

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

要:

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

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

答案 4 :(得分:0)

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吗?哪一个?为什么呢?

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