将一个字典列表转换为一个字典集合

6

如何从一个字典列表中创建一组字典?

示例:

import copy

v1 = {'k01': 'v01', 'k02': {'k03': 'v03', 'k04': {'k05': 'v05'}}}
v2 = {'k11': 'v11', 'k12': {'k13': 'v13', 'k14': {'k15': 'v15'}}}

data = []
N = 5
for i in range(N):
    data.append(copy.deepcopy(v1))
    data.append(copy.deepcopy(v2))

print data

如何从列表data创建一组字典?

NS:当两个字典在结构上完全相同时,它们是相等的。这意味着它们具有完全相同的键和值(递归地)。


你需要的元组输出是什么? - Moinuddin Quadri
1
@ForceBru TypeError:不可哈希类型:'dict' - BPL
@BPL 问题的标题不应该是“将字典的字典转换为字典集”,而不是“将字典列表转换为字典集”吗?即 list -> dict。我仍然对这个问题感到困惑。 - Moinuddin Quadri
4
forzendict包提供了frozendicts,它们是不可变且可哈希的,因此您可以创建这些字典的集合。 - Tim Fuchs
1
你需要使用 frozendicts 的 frozendicts。 - Bernhard
显示剩余8条评论
4个回答

12

一个便宜的解决方法是将你的字典序列化,例如:

import json

dset = set()

d1 = {'a':1, 'b':{'c':2}}
d2 = {'b':{'c':2}, 'a':1} # the same according to your definition
d3 = {'x': 42}

dset.add(json.dumps(d1, sort_keys=True))
dset.add(json.dumps(d2, sort_keys=True))
dset.add(json.dumps(d3, sort_keys=True))

for p in dset:
    print json.loads(p) 

从长远来看,将整个内容包装在一个类(如SetOfDicts)中会更有意义。


不错!我还没有找到任何反例,即使在字典的深层级别上键被混淆了,它似乎也能正常工作。 - BPL
@BPL:当然,只要您的字典(以及所有子元素)可序列化,这才有效。 - georg
好的,我可以接受这个 ;) - BPL

1

字典在Python中是可变的,因此不可哈希。

您可以创建一个带有__hash__方法的字典子类。确保字典的哈希值在其在集合中时不会改变(这可能意味着您不能允许修改成员)。 请参见http://code.activestate.com/recipes/414283-frozen-dictionaries/以获取frozendicts的示例实现。

如果您可以对(冻结的)字典定义排序顺序,则可以使用基于二叉树的数据结构而不是集合。这归结为下面链接提供的二分解决方案。

另请参见https://dev59.com/7XbZa4cB1Zd3GeqPK-Gg#18824158以了解为什么没有哈希的集合没有意义的解释。


1
好的,你指出了一些已经众所周知的事情,但并没有解决问题。 - BPL
你的问题是什么?为什么你想要一个集合?你只想要去除重复项吗?你想使用集合操作吗? - Bernhard
2
如果您已经知道dict不是可哈希的,那么您的问题就没有意义。那么你怎么能制作dicts的集合呢?您可以制作dict中的keysvalues或者both的集合,但不能制作dict本身的集合。 - Moinuddin Quadri

0

这可能不完全符合您的要求,因为它也包括列表:

def hashable_structure(structure):
    if isinstance(structure, dict):
        return {k: hashable_structure(v) for k, v in structure.items()}
    elif isinstance(structure, list):
        return {hashable_structure(elem) for elem in structure)}
    else:
        return structure

-1
借鉴georg的答案——他已经说得很清楚了; 但更简洁地说:
set(json.dumps(i, sort_keys=True) for i in data)

其中data是您的字典列表


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接