3 回答
TA贡献1798条经验 获得超3个赞
我假设您是按值而不是按键定义重复项。在这种情况下,您可以使用(这里提到)来展平嵌套的字典
def flatten(d):
out = {}
for key, val in d.items():
if isinstance(val, dict):
val = [val]
if isinstance(val, list):
for subdict in val:
deeper = flatten(subdict).items()
out.update({key + '_' + key2: val2 for key2, val2 in deeper})
else:
out[key] = val
return out
然后检查条件
v = flatten(d).values()
len(set(v))!=len(v)
结果为真
TA贡献1851条经验 获得超4个赞
我写了一个简单的解决方案:
dictionary = {'hello': 3 , 'world':{'this': 5 , 'is':{'a': 3, 'dict': None}}}
def get_dups(a, values=None):
if values is None: values = []
if (a in values): return True
values.append(a)
if type(a) == dict:
for i in a.values():
if (get_dups(i, values=values)):
return True
return False
print(get_dups(dictionary))
这个怎么运作
我们首先将每个保存value在一个列表中,我们将把它传递给函数。每次运行我们检查我们的当前值是否在该列表中,True一旦有重复就返回。
if (a in values): return True
接下来get_dups,如果当前索引也是字典,我们只需遍历值并运行它们。
TA贡献2012条经验 获得超12个赞
将嵌套字典转换为其值的嵌套列表:
def nested_values(v):
return map(nested_values, v.values()) if isinstance(v, dict) else v
然后将嵌套列表展平为字典中所有值的一个列表,然后检查展平的值列表是否有重复项:
from itertools import chain
def is_duplicated_value(d):
flat = list(chain.from_iterable(nested_values(d)))
return len(flat) != len(set(flat))
测试:
print is_duplicated_value( {1:'a', 2:'b', 3:{1:'c', 2:'a'}} )
print is_duplicated_value( {1:'a', 2:'b', 3:{1:'c', 2:'d'}} )
输出:
True
False
根据您的使用和字典的大小等,您可能希望将这些步骤重新转换为递归函数,该函数将每个值添加到set检查每个值是否在集合中,然后True立即添加和返回,或者False字典是否已用完。
class Duplicated(ValueError): pass
def is_dup(d):
values = set()
def add(v):
if isinstance(v, dict):
map(add, v.values())
else:
if v in values:
raise Duplicated
else:
values.add(v)
try:
add(d)
return False
except Duplicated:
return True
测试:
print is_dup( {1:'a', 2:'b', 3:{1:'c', 2:'a'}} )
print is_dup( {1:'a', 2:'b', 3:{1:'c', 2:'d'}} )
输出:
True
False
添加回答
举报