我有以下嵌套词典列表:
[{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-545',
'name': 'Users',
'type': 'group'}},
{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-545',
'name': 'Users',
'type': 'group'}},
{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-544',
'name': 'Administrators',
'type': 'group'}}]
我想让它独一无二,并尝试了不同的建议但没有成功。 有人可以帮助它在python 2.6中独一无二吗?上面的数据中没有关键/唯一字段。 我希望得到以下结果(列表的一个成员作为完整副本被删除):
[{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-545',
'name': 'Users',
'type': 'group'}},
{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-544',
'name': 'Administrators',
'type': 'group'}}]
答案 0 :(得分:5)
你需要跟踪你是否已经看过字典。遗憾的是,字典不可删除,并且不跟踪顺序,因此您需要将字典转换为 可以删除的字典。一个frozenset()
键值对(作为元组)会做,但是你需要递归地压扁:
def set_from_dict(d):
return frozenset(
(k, set_from_dict(v) if isinstance(v, dict) else v)
for k, v in d.iteritems())
这些frozenset()
个对象代表足以跟踪唯一项目的字典值:
seen = set()
result = []
for d in inputlist:
representation = set_from_dict(d)
if representation in seen:
continue
result.append(d)
seen.add(representation)
这会保留输入列表的原始顺序,减去重复项。如果您使用的是Python 2.7及更高版本,OrderedDict
在这里会有所帮助,但您使用的是Python 2.6,所以我们需要稍微详细一点。
上述方法需要O(N)时间,每个输入字典一步,因为针对集合的测试只需要O(1)常数时间。
演示:
>>> inputlist = [{'permission': 'full',
... 'permission_type': 'allow',
... 'trustee': {'id': 'SID:S-1-5-32-545',
... 'name': 'Users',
... 'type': 'group'}},
... {'permission': 'full',
... 'permission_type': 'allow',
... 'trustee': {'id': 'SID:S-1-5-32-545',
... 'name': 'Users',
... 'type': 'group'}},
... {'permission': 'full',
... 'permission_type': 'allow',
... 'trustee': {'id': 'SID:S-1-5-32-544',
... 'name': 'Administrators',
... 'type': 'group'}}]
>>> def set_from_dict(d):
... return frozenset(
... (k, set_from_dict(v) if isinstance(v, dict) else v)
... for k, v in d.iteritems())
...
>>> seen = set()
>>> result = []
>>> for d in inputlist:
... representation = set_from_dict(d)
... if representation in seen:
... continue
... result.append(d)
... seen.add(representation)
...
>>> from pprint import pprint
>>> pprint(result)
[{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-545', 'name': 'Users', 'type': 'group'}},
{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-544',
'name': 'Administrators',
'type': 'group'}}]
答案 1 :(得分:1)
您的商品为dict
,因此您无法直接使用set
(请查看冻结集或this question/answer)。
但你仍然可以比较这些项目:
>>> l[0]==l[1]
True
>>> l[0]==l[2]
False
如果元素尚未存在,只需将其添加到新列表中即可:
>>> l2=[]
>>> for i in l:
... if i not in l2:
... l2.append(i)
...
>>> pprint(l2)
[{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-545', 'name': 'Users', 'type': 'group'}},
{'permission': 'full',
'permission_type': 'allow',
'trustee': {'id': 'SID:S-1-5-32-544',
'name': 'Administrators',
'type': 'group'}}]