【问题标题】:Quickest way to dedupe list in dict [duplicate]在dict中删除重复列表的最快方法[重复]
【发布时间】:2015-10-07 08:57:47
【问题描述】:

我有一个包含列表的字典,需要一种快速删除列表的方法。

我知道如何使用 set() 函数单独删除列表的重复数据,但在这种情况下,我想要一种快速迭代字典的方法,在途中对每个列表进行重复数据删除。

hello = {'test1':[2,3,4,2,2,5,6], 'test2':[5,5,8,4,3,3,8,9]}

我希望它看起来像;

hello = {'test1':[2,3,4,5,6], 'test2':[5,8,4,3,9]}

虽然我不一定需要保留列表的原始顺序。

我尝试过使用这样的集合,但它并不完全正确(它没有正确迭代并且我丢失了第一个键)

for key, value in hello.items(): goodbye = {key: set(value)}
>>> goodbye
{'test2': set([8, 9, 3, 4, 5])}

编辑:在下面 PM 2Ring 的评论之后,我现在以不同的方式填充 dict 以避免首先出现重复。以前我使用的是列表,但是使用集合可以防止默认情况下添加重复项;

>>> my_numbers = {}
>>> my_numbers['first'] = [1,2,2,2,6,5]
>>> from collections import defaultdict
>>> final_list = defaultdict(set)
>>> for n in my_numbers['first']: final_list['test_first'].add(n)
... 
>>> final_list['test_first']
set([1, 2, 5, 6])

如您所见,根据需要,最终输出是重复数据集。

【问题讨论】:

  • 对保留顺序不感兴趣,而且我的列表也是字典的一部分。
  • 如果您不需要保持顺序,那么请使用基于集合的方法:它比基于列表的方法更有效,但如果您的列表是小,或者如果他们有几个骗子。并考虑将集合而不是列表存储为您的字典值。 OTOH,对于非常小列表,基于集合的方式可能较慢。此外,集合使用的内存比列表多一点。
  • @PM2Ring 我最后还是使用了集合,所以一开始就避免了受骗。附加到集合的 defaultdict(set) 和 .add(n) 起到了作用。 Q 已更新。

标签: python list dictionary


【解决方案1】:

您可以使用带有deduplicate 函数的列表推导来保留顺序:

def deduplicate(seq):
    seen = set()
    seen_add = seen.add
    return [ x for x in seq if not (x in seen or seen_add(x))]

{key: deduplicate(value) for key, value in hello.items()}

【讨论】:

  • 请注意:dict 推导不适用于 2.7 等较旧的 Python 版本。
  • @Daniel 它适用于 Python 2.7 ,它不适用于任何比该版本更早的版本。
  • @AnandSKumar 你是对的。我搞砸了。
  • 我在 2.7.10 上,这种方法效果很好。谢谢。将值分配为 set() (在另一个答案中)的主要优点是这将它们保留为一个列表,并且还保留了原始顺序,对吗?
【解决方案2】:

这不是迭代错误,您只是每次都将再见分配为一个新的字典。您需要分配为空字典,然后在每次迭代中将值分配给键。

goodbye = {}
for key, value in hello.items(): goodbye[key] = set(value)
>>> goodbye
{'test1': set([2, 3, 4, 5, 6]), 'test2': set([8, 9, 3, 4, 5])}

此外,由于集合不保留顺序,如果您确实想保留顺序,最好创建一个简单的迭代函数,该函数将返回一个新列表,该列表跳过已添加的值。

def uniqueList(li):
    newList = []
    for x in li:
        if x not in newList:
            newList.append(x)
    return newList


goodbye = {}
for key, value in hello.items(): goodbye[key] = uniqueList(value)
>>> goodbye
{'test1': [2, 3, 4, 5, 6], 'test2': [5, 8, 4, 3, 9]}

【讨论】:

  • 我想这就是 OP 说他的解决方案“不太正确”的原因之一,并且在预期输出中的列表 (!) 中保留了顺序。
  • 在这里操作。实际上,保持顺序并不重要。所以这种方法也适用于我的目的。我的解决方案不太正确,因为我分配了一个新值而不是追加,只剩下一个键。
  • 为了完整起见,无论如何添加了二阶保留解决方案。
【解决方案3】:

这是一种更冗长的方式,它保留了顺序并适用于所有 Python 版本:

for key in hello:
    s = set()
    l = []
    for subval in hello[key]:
        if subval not in s:
            l.append(subval)
            s.add(subval)
    hello[key] = l

【讨论】:

    【解决方案4】:
    my_list = [1,2,2,2,3,4,5,6,7,7,7,7,7,8,9,10]
    seen = set()
    print list(filter(lambda x:x not in seen and not seen.add(x),my_list))
    

    【讨论】:

      【解决方案5】:
      >>>hello = {'test1':[2,3,4,2,2,5,6], 'test2':[5,5,8,4,3,3,8,9]}    
      >>>for key,value in hello.iteritems():
             hello[key] = list(set(value))
      >>>hello
      {'test1': [2, 3, 4, 5, 6], 'test2': [8, 9, 3, 4, 5]}
      

      【讨论】:

      • 啊酷,这把“集合”重新变成了一个列表。
      猜你喜欢
      • 2010-12-13
      • 2018-03-13
      • 2019-07-26
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 2012-12-20
      • 2018-05-07
      相关资源
      最近更新 更多