我有一个带有嵌套字典数据对象的类。我需要从中获取所有关键值。最好的有效方法是什么?
我坚持以下几点:
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var dateOfBirth = (DateTime)value;
var currentDate = DateTime.UtcNow;
var minimumAge = new DateTime(currentDate.Year - 17, currentDate.Month, currentDate.Day, currentDate.Hour, currentDate.Minute, currentDate.Second);
var maximumAge = new DateTime(currentDate.Year - 34, currentDate.Month, currentDate.Day, currentDate.Hour, currentDate.Minute, currentDate.Second);
var isTooYoung = dateOfBirth > minimumAge;
var isTooOld = dateOfBirth < maximumAge;
if (isTooYoung || isTooOld)
{
// it is about this line
var localizer = (ILocalizer)validationContext.GetService(typeof(ILocalizer));
var error = localizer.GetString(ErrorMessageString);
return new ValidationResult(error);
}
return ValidationResult.Success;
}
这是数据:
for k,v in data.items():
print v.keys()
答案 0 :(得分:3)
将列表(您的value.keys()
列表)连接为一个优雅的方法是使用双循环列表理解,如下所示:
nested_keys = [
key
for val in data.values()
for key in val.keys()]
答案 1 :(得分:1)
使用发电机:
def all_keys(d):
for k, v in d.items():
yield k
# assume that anything with `items` property will be a mapping
# this can be replaced with: `isinstance(v, dict)` or `isinstance(v, collections.Mapping)`
if hasattr(v, 'items'):
yield from all_keys(v)
根据您的输入,将产生:
data = {
"BANK": {
"no_data": "INT",
},
"SHOCK": {
"drop": "NOTI",
"rise": "NOTI",
"high_risk": "ALERT",
},
"OFFLINE": {"online": None, "offline_few": "ALERT"},
}
print(list(all_keys(data)))
# ['BANK', 'no_data', 'SHOCK', 'drop', 'rise', 'high_risk', 'OFFLINE', 'online', 'offline_few']
答案 2 :(得分:0)
递归函数
获取嵌套字典各个级别的所有键
def get_keys(d, result = None):
# use default of None to fix issue noted by @Ch3steR
# namely: http://effbot.org/zone/default-values.htm
if result is None:
result = []
for k, v in d.items():
if isinstance(v, dict):
result.append(k)
get_keys(v, result)
else:
result.append(k)
return result
测试
print(get_keys(data))
输出
['BANK', 'no_data', 'SHOCK', 'drop', 'rise', 'high_risk', 'OFFLINE', 'online', 'offline_few']
答案 3 :(得分:0)
如果所有“实际”键值对都位于某个深度(例如深度1),则可以这样:
data = {
"BANK": {
"no_data": "INT",
},
"SHOCK": {
"drop": "NOTI",
"rise": "NOTI",
"high_risk": "ALERT",
},
"OFFLINE": {"online": None, "offline_few": "ALERT"},
}
dic = {k:v for val in data.values() for k,v in val.items()}
但是,如果您不知道:
data = {
"BANK": {
"no_data": "INT",
},
"SHOCK": {
"drop": "NOTI",
"rise": "NOTI",
"high_risk": "ALERT",
},
"online": None,
"offline_few": "ALERT"
}
在这种情况下,您需要使用递归:
def unnest(dic, final=dict()):
for key, val in dic.items():
if not isinstance(val, dict):
final[key] = val
else:
dic2 = dict()
for k, v in val.items():
dic2[k] = v
unnest(dic2, final)
return final
dic = unnest(data, {}) #every use of the function should have {} to solve issue pointed by @Ch3steR
在任何情况下,一旦有了“未嵌套”的字典,就很难打印出键:
print(dic.keys())