如何在Python中从列表中删除重复的元组?

3
我有一个包含元组列表的列表,如下所示。
mylist = [['xxx', 879], ['yyy', 315], ['xxx', 879], ['zzz', 171], ['yyy', 315]]

我想从mylist中删除重复的元组,并获得以下输出。
mylist = [['xxx', 879], ['yyy', 315], ['zzz', 171]]

看起来在Python中,set无法正常工作。

mylist = list(set(mylist))

有没有用Python(或者使用库)快速简便的方式来完成这个任务?

或者如果您不需要保留顺序,请查看在列表中删除重复项 - jdehesa
1
我不认为这个问题是那个特定问答的重复,尽管我猜想可能有更好的答案存在... - cs95
1
你遇到问题的原因是,你有一个列表嵌套列表,而列表无法被添加到集合中,因为列表不是可哈希对象。 - John Joseph Fernandes
4个回答

6

看起来你想保持顺序。在这种情况下,您可以保留一个集合来跟踪已添加的列表。

以下是一个示例:

mylist = [['xxx', 879], ['yyy', 315], ['xxx', 879], ['zzz', 171], ['yyy', 315]]

# set that keeps track of what elements have been added
seen = set()

no_dups = []
for lst in mylist:

    # convert to hashable type
    current = tuple(lst)

    # If element not in seen, add it to both
    if current not in seen:
        no_dups.append(lst)
        seen.add(current)

print(no_dups)

输出结果如下:

[['xxx', 879], ['yyy', 315], ['zzz', 171]]

注意:由于列表不可哈希,所以您可以将元组添加到seen集合中。


@cᴏʟᴅsᴘᴇᴇᴅ 看起来它保留了元素在原始列表中遇到的顺序? - Jonathon McMurray

6

你无法实现这个功能是因为你有一个列表的列表,而不是元组的列表。

你可以采取以下措施:

mytuplelist = [tuple(item) for item in mylist]
mylist = list(set(mytuplelist))

或者
mylist = list(set(map(tuple, mylist)))

@NickA 不,但根据他们的输出,我有理由相信可能是这样的,除非OP澄清。 :) - cs95
@cᴏʟᴅsᴘᴇᴇᴅ 尊敬的,您可以在问题评论部分这样做。 - Ma0
@NickA,我很抱歉过早地发表了意见!我已经编辑了我的答案,使其更加合适,并且不会再推销这个想法,因为它显然对OP不再重要。 - cs95
1
@cᴏʟᴅsᴘᴇᴇᴅ 看起来很棒,点个赞! - Nick stands with Ukraine
你也可以这样做: mylist = list(set(map(tuple, mylist))) - John Joseph Fernandes

5
你需要编写代码,仅保留子列表中的第一个,并删除其余部分。最简单的方法是反转 mylist ,将其加载到 dict 对象中,并再次将其键值对检索为列表。
>>> list(map(list, dict(mylist).items()))

或者,使用一个 列表推导式 -

>>> [list(v) for v in dict(mylist).items()]

[['zzz', 171], ['yyy', 315], ['xxx', 879]]

请注意,此答案不保持顺序!另外,如果您的子列表可以有两个以上的元素,则涉及哈希化数据的元组版本的方法,如@ JohnJosephFernandez的答案所示,将是最好的选择。


你能解释一下反转背后的逻辑吗?另外,我认为这在处理类似 mylist = [['xxx', 879], ['xxx', 200]] 这样的情况时会失败。 - Chris_Rands
@Chris_Rands 抱歉,它们是旧解决方案的一部分,我应该将它们删除。它们在那里没有任何作用。 - cs95
@Chris_Rands 我必须承认,一开始我误读了问题,认为关键字(第一个子列表项)是相同的,并且 OP 想要第一个,删除所有其他重复项。因此,我反转了列表并将条目发送到字典中,以便在检索时,最后插入的键值对会覆盖先前的键值对,这些键值对是原始列表中的第一对。希望我的解释有意义! - cs95
我来晚了,所以没有关注问题的演变,但事实是[list(v) for v in dict([['xxx', 879], ['xxx', 200]]).items()]不等于list(set(tuple(item) for item in [['xxx', 879], ['xxx', 200]])),我认为后者(就像John Joseph写的那样)才是想要的。但是OP接受了你的答案,所以我可能是错的!也许在他们的数据中根本不会出现这种情况。 - Chris_Rands
1
@Chris_Rands 是的,我自己也很惊讶,我不怕承认我在回答时有些困难!嗯,OPs是善变的生物,我已经进行了必要的编辑和免责声明,希望现在可以了。 ;) - cs95

2

另一个选择:

>>> mylist = [['xxx', 879], ['yyy', 315], ['xxx', 879], ['zzz', 171], ['yyy', 315]]
>>> y = []
>>> for x in mylist:
...     if not x in y:
...             y+=[x]
...
>>> y
[['xxx', 879], ['yyy', 315], ['zzz', 171]]

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