【问题标题】:Applying set operation on list of dictionary对字典列表应用集合操作
【发布时间】:2016-08-24 05:30:29
【问题描述】:

我的列表多次包含相同的字典,例如

喜欢

[ {'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}, {'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}]

当我对其应用 set 操作以使其与众不同时,它给出了

TypeError: unhashable type: 'dict'

使这种列表项与众不同的正确方法是什么?

【问题讨论】:

    标签: python list dictionary set


    【解决方案1】:

    字典是可变对象,因此不能存储在集合中。您可以将字典转换为表示相同数据的不可变对象;在对这些应用set() 操作后,您可以转换回字典:

    unique = [dict(t) for t in set(tuple(sorted(d.items())) for d in l)]
    

    这会将每个字典转换为包含所有键值对的排序元组;这假定字典中的 也是不可变的。

    之所以需要排序,是因为可能会产生两个具有相同键值对但由于哈希冲突而以不同顺序列出它们的字典;两个键可以映射到同一个哈希表槽,但首先插入的将获胜:

    >>> {'bar': 42, 'baz': 81} == {'baz': 81, 'bar': 42}
    True
    >>> list({'bar': 42, 'baz': 81}) == list({'baz': 81, 'bar': 42})  # compare keys in order
    False
    

    【讨论】:

      【解决方案2】:

      一种直接的方法是将每个dict 转换为字符串并在其上使用set,然后将每个字符串转换回dict

      >>> import ast
      >>> l=[ {'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}, {'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}]
      >>> l
      [{'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}, {'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}]
      >>> [ast.literal_eval(i) for i in set(map(str, l))]
      [{'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}]
      >>>
      

      另一种用于不同排序的方法,我们将每个dict 转换为tuple

      >>> l=[ {'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}, {'gram': '1', 'name': 'ZYLOG SYSTEMS LTD'}]
      >>> set([tuple(d.items()) for d in l])
      {(('name', 'ZYLOG SYSTEMS LTD'), ('gram', '1'))}
      >>> [dict(i) for i in set([tuple(sorted(d.items())) for d in l])]
      [{'name': 'ZYLOG SYSTEMS LTD', 'gram': '1'}]
      >>>
      

      【讨论】:

      • 根据哈希冲突的存在方式以及输入字典的创建方式,字符串表示中键的确切顺序很容易不同,即使对于实际上是相等。
      • 试试你的方法[{'bar': 42, 'baz': 81}, {'baz': 81, 'bar': 42}],例如。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-29
      • 2016-09-27
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 2010-09-14
      相关资源
      最近更新 更多