从列表中删除重复的子列表

Mar*_*oss 1 python list duplicates duplicate-removal

如果我有这样一个列表:

mylist = [[1,2,3], ['a', 'c'], [3,4,5],[1,2], [3,4,5], ['a', 'c'], [3,4,5], [1,2]]
Run Code Online (Sandbox Code Playgroud)

删除重复子列表的最佳方法是什么?

现在我用这个:

y, s = [ ], set( )
for t in mylist:
    w = tuple( sorted( t ) )
    if not w in s:
        y.append( t )
        s.add( w )
Run Code Online (Sandbox Code Playgroud)

它有效,但我想知道是否有更好的方法?更蟒蛇般的东西?

iCo*_*dez 8

您可以使用OrderedDict.fromkeys从列表中过滤重复项,同时仍保留顺序:

>>> from collections import OrderedDict
>>> mylist = [[1,2,3], ['a', 'c'], [3,4,5],[1,2], [3,4,5], ['a', 'c'], [3,4,5], [1,2]]
>>> map(list, OrderedDict.fromkeys(map(tuple, mylist)))
[[1, 2, 3], ['a', 'c'], [3, 4, 5], [1, 2]]
>>>
Run Code Online (Sandbox Code Playgroud)

map(tuple, mylist)是必要的,因为字典键必须是可清除的(列表不是因为您可以添加/删除它们中的项目).


Sec*_*ret 7

将元素转换为元组*,然后将整个事物转换为集合,然后将所有内容转换回列表:

m = [[1,2,3], ['a', 'c'], [3,4,5],[1,2], [3,4,5], ['a', 'c'], [3,4,5], [1,2]]

print [list(i) for i in set(map(tuple, m))]
Run Code Online (Sandbox Code Playgroud)

*我们正在转换为元组,因为列表是不可清除的(因此我们不能在它们上使用set


小智 5

好吧,因为sets本身就是重复数据删除,你的第一直觉可能就是这样set(mylist).但是,这不太有效:

In [1]: mylist = [[1,2,3], ['a', 'c'], [3,4,5],[1,2], [3,4,5], ['a', 'c'], [3,4,5], [1,2]]

In [2]: set(mylist)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-b352bcae5975> in <module>()
----> 1 set(mylist)

TypeError: unhashable type: 'list'
Run Code Online (Sandbox Code Playgroud)

这是因为sets只能处理可iterable散列元素(并且因为lists是可变的,所以它们是不可散列的).

相反,您只需将子列表转换为子元素的价格即可:

In [3]: set([tuple(x) for x in mylist])
Out[3]: {(1, 2), (1, 2, 3), (3, 4, 5), ('a', 'c')}
Run Code Online (Sandbox Code Playgroud)

或者,如果您确实需要再次列出一个列表:

In [4]: [list(x) for x in set([tuple(x) for x in mylist])]
Out[4]: [[1, 2], [3, 4, 5], ['a', 'c'], [1, 2, 3]]
Run Code Online (Sandbox Code Playgroud)