我有一个这种形式的字典:
d = {
'A': {
'a1': {3},
'a2': {2},
'a3': {1},
},
'B': {
'b1': {1},
},
'C': {
'c1': {2, 3},
}
}
我还有其他类似形式的词典,但我的目标是确定数字1,2,3
是否存在于键A, B, and C
的值中。
在上面的字典d
中,答案是True
,因为我有:
A.a2
包含2
B.b1
包含1
C.c1
包含3
所以在字典d
中我有值1,2,3
保证只有3个键A, B, C
和3个嵌套键a1, a2, a3
(b1,c1相同)。此外,每组中唯一可能的值为1,2,3
。
我可以迭代字典的所有排列,但我认为不会那么有效。想知道在A,B,C
以下是其他词典的一些示例输出:
VALID
A.a2 - > 2,B.b1 - > 1,C.c1 - > 3
{
' A':{
' a1':{3},
' a2':{2},
' a3':{1},
},
' B':{
' b1':{1},
},
' C':{
' c1':{2,3},
}
}
INVALID
我们有B.b1 - > 1,C.c1 - > 2
我们需要A.a3 - > 3
OR
仍然无效
我们有B.b1 - > 1,C.c1 - > 3
我们需要A.a3 - > 2
{
' A':{
' a3':{1},
},
' B':{
' b1':{1},
},
' C':{
' c1':{2,3},
' c2':{1}
}
}
VALID
我们有B.b1 - > 1,A.a2 - > 2,C.c1 - > 3
我们在每个第一级Key中都有1,2,3个序列!
{
' A':{
' a2':{2}
},
' B':{
' b1':{1},
},
' C':{
' c1':{2,3},
}
}
答案 0 :(得分:1)
这是一个生成器,它解开A B和C的嵌套子句: 然后检查A B和C内容之间的所有联合,其元素至少与参与的子区域一样多。
def unravel_nested(d):
for v in d.values():
if isinstance(v, dict):
yield from v.values()
else:
yield v
content = [functools.reduce(set.union, unravel_nested(d[X])) for X in 'ABC']
all(len(functools.reduce(set.union, comb)) >= k for k in range(1,4) for comb in itertools.combinations(content, k))
# True
答案 1 :(得分:1)
这是我将如何做到的。我知道我可以删除字典(好),但我认为这对于学习是好的:
d = {
'A': {
'a1': [3],
'a2': [2],
'a3': [1]
},
'B': {
'b1': [1]
},
'C': {
'c1': [2, 3]
}
}
def checkDictionary(di):
good = {1:False,2:False,3:False}
for key in di:
for key2 in di[key]:
for item in di[key][key2]:
if item in good:
good[item] = True
return good[1] and good[2] and good[3]
print(checkDictionary(d))
答案 2 :(得分:1)
>>> import itertools as it
>>> d
{'A': {'a1': set([3]), 'a3': set([1]), 'a2': set([2])}, 'C': {'c1': set([2, 3])}, 'B': {'b1': set([1])}}
>>> #iterate every key and vaue in dict
>>> [v for k,v in d.iteritems()]
[{'a1': set([3]), 'a3': set([1]), 'a2': set([2])}, {'c1': set([2, 3])}, {'b1': set([1])}]
>>> #iterate through every subdict
>>> [[value for key,value in v.iteritems()] for k,v in d.iteritems()]
[[set([3]), set([1]), set([2])], [set([2, 3])], [set([1])]]
>>> #join list of sets to a single list using itertools chain()
>>> #convert the iterools object to list
>>> [list(it.chain.from_iterable([value for key,value in v.iteritems()])) for k,v in d.iteritems()]
[[3, 1, 2], [2, 3], [1]]
>>> #sort every items in sublist
>>> [sorted(it.chain.from_iterable([value for key,value in v.iteritems()])) for k,v in d.iteritems()]
[[1, 2, 3], [2, 3], [1]]
>>> #sort all items in list
>>> sorted([sorted(it.chain.from_iterable([value for key,value in v.iteritems()])) for k,v in d.iteritems()])
[[1], [1, 2, 3], [2, 3]]
>>> #enumerate and check if each element in check([1,2,3]) is present in each index of obtained list
>>> [i for index,i in enumerate(sorted([sorted(it.chain.from_iterable([value for key,value in v.iteritems()])) for k,v in d.iteritems()])) if check[index] in i]
[[1], [1, 2, 3], [2, 3]]
是你需要的!
简化列表理解以便更好地理解,
>>> import itertools as it
>>> check = [1, 2, 3]
>>> d={'A': {'a1': set([3]), 'a3': set([1]), 'a2': set([2])}, 'C': {'c1': set([2, 3])}, 'B': {'b1': set([1])}}
>>> True if len([i for ind,i in enumerate(sorted([sorted(it.chain.from_iterable([value for key,value in v.iteritems()])) for k,v in d.iteritems()])) if check[ind] in i])==len(check) else False
True
>>> d={'A': {'a1': set([3]), 'a3': set([1])}, 'C': {'c1': set([1])}, 'B': {'b1': set([1])}}
>>> True if len([i for index,i in enumerate(sorted([sorted(it.chain.from_iterable([value for key,value in v.iteritems()])) for k,v in d.iteritems()])) if check[index] in i])==len(check) else False
False
现在将此结果的len与check的结果进行比较。如果它们相等,则为True,否则为False。
说以下内容应该给出所需的结果,
pytest <filename>.py arg1