如何从python中的列表中删除重复的元组?
Posted
技术标签:
【中文标题】如何从python中的列表中删除重复的元组?【英文标题】:How to remove duplicate tuples from a list in python? 【发布时间】:2018-01-17 11:51:37 【问题描述】:我有一个包含如下元组列表的列表。
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 中是否有任何快速简便的方法(可能使用库)?
【问题讨论】:
How do you remove duplicates from a list in whilst preserving order?的可能重复 或者如果您不需要保留订单,请查看Removing duplicates in lists。 我不相信这个问题是那个特定问答的重复,虽然我猜有一个更好的... 它不适合您的原因是,您有一个 list 列表,并且无法将列表添加到集合中,因为列表不可散列。 【参考方案1】:您似乎想保持秩序。在这种情况下,您可以保留一组跟踪已添加的列表。
这是一个例子:
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ᴘᴇᴇᴅ 它似乎保留了元素在原始列表中遇到的顺序?【参考方案2】:您无法执行此操作的原因是您有一个列表列表,而不是一个元组列表。
你可以做的是:
mytuplelist = [tuple(item) for item in mylist]
mylist = list(set(mytuplelist))
或
mylist = list(set(map(tuple, mylist)))
【讨论】:
@NickA 不,但我确实有理由相信根据他们的输出可能是这种情况,除非 OP 澄清。 :) @cᴏʟᴅsᴘᴇᴇᴅ 尊敬的,您可以在问题评论部分这样做。 @NickA 我为我的过激行为道歉!我已经将我的答案编辑得更合适一些,并且将停止插入这个想法,因为它显然对 OP 来说已经无关紧要了。 @cᴏʟᴅsᴘᴇᴇᴅ 看起来很棒,有一个罕见的 +1 你也可以做一个 mylist = list(set(map(tuple, mylist)))【参考方案3】:您需要编写代码来保留第一个子列表,删除其余的。最简单的方法是反转mylist
,将其加载到dict
对象中,然后再次将其键值对作为列表检索。
>>> list(map(list, dict(mylist).items()))
或者,使用 列表推导 -
>>> [list(v) for v in dict(mylist).items()]
[['zzz', 171], ['yyy', 315], ['xxx', 879]]
请注意,此答案不维持秩序!此外,如果您的子列表可以包含 2 个以上的元素,那么像@JohnJosephFernandez' answer 所示,涉及对数据的元组版本进行哈希处理的方法将是最好的做法。
【讨论】:
你能解释一下反转背后的逻辑吗?我也认为这对于mylist = [['xxx', 879], ['xxx', 200]]
之类的东西会失败
@Chris_Rands 抱歉,它们是我应该删除的旧解决方案的一部分。他们在那里什么都不做。
@Chris_Rands 我不得不承认我一开始确实误读了这个问题,认为键(第一个子列表项)是相同的,而 OP 想要第一个,删除所有其他重复项。正因为如此,我反转了列表并将条目发送到一个字典中,这样,当检索回来时,最后插入的键值对(覆盖前面的键值对)是原始列表中的第一对。我希望我说得通!
好吧,我来晚了,所以没有关注问题的演变,但事实仍然是[list(v) for v in dict([['xxx', 879], ['xxx', 200]]).items()]
不是list(set(tuple(item) for item in [['xxx', 879], ['xxx', 200]]))
,我认为后者(如约翰约瑟夫所写)是通缉。但是 OP 接受了你的回答,所以我可能错了!也许这种情况永远不会出现在他们的数据中
@Chris_Rands 是的,我自己很惊讶,我不怕承认我做了一顿回答!好吧,OP 是善变的野兽,我已经进行了必要的编辑和免责声明,我希望现在就这样。 ;)【参考方案4】:
另一种选择:
>>> 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]]
【讨论】:
以上是关于如何从python中的列表中删除重复的元组?的主要内容,如果未能解决你的问题,请参考以下文章
如何根据元组的索引值从列表中删除重复的元组,同时保持元组的顺序? [复制]