Python中的列表集合(set)

44

我有一个嵌套列表

mat = [[1,2,3],[4,5,6],[1,2,3],[7,8,9],[4,5,6]]

我希望将其转换为一个集合,即删除重复的列表并创建一个仅包含唯一列表的新列表。

在上述情况下,所需的答案将是

[[1,2,3],[4,5,6],[7,8,9]]

但是当我执行set(mat)时,它给我错误

类型错误:不可哈希类型:'list'

请问你能解决我的问题吗?提前致谢!


1
顺序重要吗? - thefourtheye
4个回答

59
由于列表是可变的,因此无法进行哈希处理。最好的方法是将它们转换为元组并形成一个集合,就像这样。
>>> mat = [[1,2,3],[4,5,6],[1,2,3],[7,8,9],[4,5,6]]
>>> set(tuple(row) for row in mat)
set([(4, 5, 6), (7, 8, 9), (1, 2, 3)])

我们逐个遍历mat,一次一个列表,将其转换为元组(它们是不可变的,所以set可以与它们配合使用),并将生成器发送到set函数。
如果您想要作为列表列表的结果,可以通过将set函数调用的结果转换为列表来扩展相同的内容,例如:
>>> [list(item) for item in set(tuple(row) for row in mat)]
[[4, 5, 6], [7, 8, 9], [1, 2, 3]]

8

列表是可变的,因此不可哈希。请使用元组代替。

In [114]: mat = [[1,2,3],[4,5,6],[1,2,3],[7,8,9],[4,5,6]]

In [115]: mat = [tuple(t) for t in mat]

In [116]: matset = set(mat)

In [117]: matset
Out[117]: {(1, 2, 3), (4, 5, 6), (7, 8, 9)}

In [118]: [list(t) for t in matset]
Out[118]: [[4, 5, 6], [7, 8, 9], [1, 2, 3]]

6
@thefourtheye的回答清晰地描述了您遇到的不可哈希数据类型问题以及绕过它的方法,以便您可以创建一个集合并删除重复项。这应该足以解决大部分问题,但是重新阅读您的问题,
在上述情况下,所需的答案将是[[1,2,3],[4,5,6],[7,8,9]]。
如果顺序很重要,则需要使用OrderedDict
>>> from collections import OrderedDict
>>> map(list, OrderedDict.fromkeys(map(tuple, mat)).keys())
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

0

将列表作为字典或集合的键是无效的。因为当我们想要访问字典中的值时,键应该保持不变。例如,值可以改变,但键始终保持不变。

所以在你的情况下:

mat = [[1,2,3],[4,5,6],[1,2,3],[7,8,9],[4,5,6]]

我们需要将内部列表转换为元组。可以通过以下方式完成:
map(tuple, mat)

现在,元组可以用作集合/字典的键,因为元组的键不可更改。
dict.fromkeys(map(tuple, mat))

由于我们需要将最终答案作为列表的列表返回,因此我们需要将字典的所有元组键转换为列表。 我们不关心值,因此我们只从字典中读取键并将其转换为列表。

   mat = map(list, dict.fromkeys(map(tuple, mat)).keys())

现在,mat看起来会像这样。
mat = [[1,2,3],[4,5,6],[7,8,9]]

在Python 3.8+中,字典将会保存原有的顺序,如果使用较旧版本,则可以使用OrderedDict

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