我使用以下代码来验证字典(a)与另一个字典(check_against)的对比。不幸的是我的代码不是很易读,所以我想知道是否有更快/更清晰的内置解决方案来实现相同的结果。也许我还没有使用正确的关键字搜索,但我还没有找到任何关于我认为是一项相当普遍的任务的讨论。
check_against = {
'a' : str,
'b' : {
'c': int,
'd': int,
}
}
a = {
'a' : 1,
'c' : 1
}
def get_type_at_path(obj, chain):
_key = chain.pop(0)
if _key in obj:
return key_exists(obj[_key], chain) if chain else type(obj[_key])
def root_to_leaf_paths(tree, cur=()):
if isinstance(tree,dict):
for n, s in tree.items():
for path in root_to_leaf_paths(s, cur+(n,)):
yield path
else:
yield [cur,tree]
for path,value_type in root_to_leaf_paths(check_against):
a_value_type = get_type_at_path(a,list(path))
if a_value_type == None:
print(f"Missing key at path \"{list(path)}\"")
elif not a_value_type == value_type:
print(f"Value at path \"{list(path)}\" should be of type \"{value_type}\" but got {a_value_type}")
输出
Value at path "['a']" should be of type "<class 'str'>" but got <class 'int'>
Missing key at path "['b', 'c']"
Missing key at path "['b', 'd']"
答案 0 :(得分:2)
您可以稍微调整<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="@integer/config_shortAnimTime">
<translate
android:fromYDelta="-20%"
android:toYDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:interpolator="@android:anim/decelerate_interpolator"
/>
<scale
android:fromXScale="105%"
android:fromYScale="105%"
android:toXScale="100%"
android:toYScale="100%"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="@android:anim/decelerate_interpolator"
/>
</set>
功能,将其视为一般字典拼合器。展平架构和数据。然后比较是微不足道的。
root_to_leaf_paths()
答案 1 :(得分:1)
您可以将check_against
词典展平为仅包含映射到类型的键,然后针对a
运行:
check_against = {'a': <class 'str'>, 'b': {'c': <class 'int'>, 'd': <class 'int'>}}
a = {'a': 1, 'c': 1}
def flatten(d):
_v = [[(a, b)] if not isinstance(b, dict) else flatten(b) for a, b in d.items()]
return [i for b in _v for i in b]
new_check = dict(flatten(check_against))
for c, d in a.items():
if not isinstance(d, new_check[c]):
raise TypeError("At key '{}': expecting value of type '{}', got '{}'".format(c, new_check[c].__name__, type(d).__name__))
运行时,检查成功引发错误类型的错误:
TypeError: At key 'a': expecting value of type 'str', got 'int'
编辑:利用a
作为检查词典:
def check_values(d, check_dict = a):
for a, b in d.items():
if a in check_dict and not isinstance(check_dict[a], b):
raise TypeError("At key '{}': expecting type '{}' but got '{}'".format(a, type(check_dict[a]).__name__, b.__name__))
if isinstance(b, dict):
check_values(b)
输出:
TypeError: At key 'a': expecting type 'int' but got 'str'