从python中的列表中删除重复的JSON对象

时间:2015-11-27 10:21:46

标签: python json list dictionary generator

我有一个dict列表,其中特定值重复多次,我想删除重复的值。

我的清单:

te = [
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
        "Name": "Bala",
        "phone": "None"
      }
    ]

删除重复值的功能:

def removeduplicate(it):
    seen = set()
    for x in it:
        if x not in seen:
            yield x
            seen.add(x)

当我调用此函数时,我得到generator object

<generator object removeduplicate at 0x0170B6E8>

当我尝试迭代生成器时,我得到TypeError: unhashable type: 'dict'

有没有办法删除重复值或迭代生成器

3 个答案:

答案 0 :(得分:11)

您可以通过字典理解轻松删除重复键,因为字典不允许重复键,如下所示 -

(1*(8^1) + 5*(8^0) ) + (7*(16^1) + 1*(16^0)) + (5*(10^0)) = 133

输出 -

te = [
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
        "Name": "Bala",
        "phone": "None"
      },
      {
          "Name": "Bala1",
          "phone": "None"
      }      
    ]

unique = { each['Name'] : each for each in te }.values()

print unique

答案 1 :(得分:2)

因为您无法将dict添加到set。来自this question

  

您尝试将dict用作另一个dictset的密钥。这不起作用,因为键必须是可清洗的。

     

作为一般规则,只有不可变对象(字符串,整数,浮点数,frozensets,不可变元组)是可以清除的(尽管例外是可能的)。

>>> foo = dict()
>>> bar = set()
>>> bar.add(foo)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> 

相反,您已经在使用if x not in seen,所以只需使用一个列表:

>>> te = [
...       {
...         "Name": "Bala",
...         "phone": "None"
...       },
...       {
...         "Name": "Bala",
...         "phone": "None"
...       },
...       {
...         "Name": "Bala",
...         "phone": "None"
...       },
...       {
...         "Name": "Bala",
...         "phone": "None"
...       }
...     ]

>>> def removeduplicate(it):
...     seen = []
...     for x in it:
...         if x not in seen:
...             yield x
...             seen.append(x)

>>> removeduplicate(te)
<generator object removeduplicate at 0x7f3578c71ca8>

>>> list(removeduplicate(te))
[{'phone': 'None', 'Name': 'Bala'}]
>>> 

答案 2 :(得分:1)

您仍然可以使用set进行重复检测,只需将字典转换为可清除的内容,例如tuple。您的词典可以通过tuple(d.items())转换为元组,其中d是字典。将其应用于您的生成器函数:

def removeduplicate(it):
    seen = set()
    for x in it:
        t = tuple(x.items())
        if t not in seen:
            yield x
            seen.add(t)

>>> for d in removeduplicate(te):
...    print(d)
{'phone': 'None', 'Name': 'Bala'}

>>> te.append({'Name': 'Bala', 'phone': '1234567890'})
>>> te.append({'Name': 'Someone', 'phone': '1234567890'})

>>> for d in removeduplicate(te):
...    print(d)
{'phone': 'None', 'Name': 'Bala'}
{'phone': '1234567890', 'Name': 'Bala'}
{'phone': '1234567890', 'Name': 'Someone'}

这提供了比“看见”list(O(n))更快的查找(平均O(1))。是否值得将每个字典转换为元组的额外计算取决于您拥有的字典数量以及有多少重复字典。如果有很多重复,“看到”list会变得非常大,并且测试是否已经看到dict可能会成为一项昂贵的操作。这可能证明元组转换是合理的 - 你必须测试/分析它。