从列表中删除重复的词典

时间:2014-08-01 11:33:44

标签: python dictionary list-comprehension duplicate-removal

我列出了具有相同键和不同值的词典,但有时可能是重复的:

[{'colorName': u'red',
  'color_thumb': [],
  'main_zoom_picture': u'webcontent/0007/991/393/cn7991393.jpg',
  'pic_uris': [(u'S', u'webcontent/0007/991/248/cn.jpg')],
  'swatch_image_path': u'webcontent/0007/991/248/cn7991248.jpg'},
 {'colorName': u'red',
  'color_thumb': [],
  'main_zoom_picture': u'webcontent/0007/991/393/cn7991393.jpg',
  'pic_uris': [(u'S', u'webcontent/0007/991/248/cn.jpg')],
  'swatch_image_path': u'webcontent/0007/991/248/cn7991248.jpg'}]

我在做:

[dict(tupleized) for tupleized in set(tuple(item.items()) for item in shared_list)]

接收:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

3 个答案:

答案 0 :(得分:4)

这对我的数据集起了作用。

from itertools import groupby

print [k for k,v in groupby(sorted(shared_list))]

采取from this question

答案 1 :(得分:1)

你的环被倒置了;你需要首先遍历shared_list *:

[dict(tupleized) for item in shared_list for tupleized in set(tuple(item.items()))]

列表推导按嵌套顺序列出循环;左边是最外面的。

下一个问题是您的值包含列表,这些列表无法添加到未更改的集合中。

接下来,您需要在循环中使用外部集来测试之前是否有字典:

def immutable_repr(d):
    return tuple((k, tuple(v)) if isinstance(v, list) else v
                 for k, v in sorted(d.items()))

seen = set()
[d for d in shared_list if immutable_repr(d) not in seen and not seen.add(immutable_repr(d))]

这里immutable_repr()负责从每个字典中生成一个不可变元组:

>>> immutable_repr(shared_list[0])
(u'red', ('color_thumb', ()), u'webcontent/0007/991/393/cn7991393.jpg', ('pic_uris', ((u'S', u'webcontent/0007/991/248/cn.jpg'),)), u'webcontent/0007/991/248/cn7991248.jpg')

排序确保即使对于具有不同键顺序的字典(可以根据字典的插入和删除历史进行更改),看到它仍然有效的测试。

seen用于跟踪到目前为止看到的内容,以过滤掉任何后续重复内容:

>>> from pprint import pprint
>>> seen = set()
>>> pprint([d for d in shared_list if immutable_repr(d) not in seen and not seen.add(immutable_repr(d))])
[{'colorName': u'red',
  'color_thumb': [],
  'main_zoom_picture': u'webcontent/0007/991/393/cn7991393.jpg',
  'pic_uris': [(u'S', u'webcontent/0007/991/248/cn.jpg')],
  'swatch_image_path': u'webcontent/0007/991/248/cn7991248.jpg'}]

答案 2 :(得分:0)

Martijin Pieters&#39;关于列表理解中的错误的解释是正确的。为列表中的每个dict返回的items()将是一个列表。换句话说,集合不能散列列表列表。

但是,您可以在一个集合中存储元组元组。因此,您可以对您的代码行进行以下更改。

>>> [dict(tupleized) for tupleized in set([tuple(tup for tup in item.items()) for item in shared_list]

另外,Christoph Hegemann的回答非常优雅。如果你有时间和倾向,请检查itertools(我最近发现它并且它很好用)。

我向Christoph道歉,因为我会对你的答案进行投票,但我最近才成为社区成员。所以我没有代表:(