Python: 如何查看对象键值对的数据类型?
Python: How to check the data type of key-value pair of an object?
我正在创建一个函数来将每个数组(家庭作业、测验、测试)的标记添加到一个对象(student1)中。当代码尝试添加 "Lloyd" 时,肯定会出现错误。
我想查看"name"的value的data-type,只有当[=14= key 的 ]value 是数字。请建议。
student1 = {
"name": "Lloyd",
"homework": [90, 97, 75, 92],
"quiz": [88, 40, 94],
"test": [75, 90]
}
def eachSubjAverage(std):
for item in std:
total = sum(std[item]) #totalling each marks
std[item].append(total)
average_no = total/(len(std[item])-1) #averaging the marks
std[item].append(average_no)
eachSubjAverage(student1)
您可以检查该值是否可迭代:
hasattr(std[item], '__iter__')
然后检查每个成员是 Number:
all( map ( lambda x: isinstance(x,numbers.Number), std[item] ) )
您可以使用 try except
:
for item in std:
try:
total = sum(std[item])
except TypeError:
pass
for item in std:
if isinstance(std[item],list):
total = sum(std[item])
如果你想确保列表中的元素是int
类型,那么
for item in std:
if isinstance(std[item],list) and all(isinstance(e,int) for e in student1[item]):
total = sum(std[item])
了解 isinstance() 方法
一个明显的例子 XY problem...
您真正的问题是错误的数据结构以相同的方式存储异构信息(学生的姓名及其分数)。 RightSolution(tm)是使用更好的数据结构,即:
student1 = {
"personal_infos" : {
"name": "Lloyd",
},
"marks": {
"homework": [90, 97, 75, 92],
"quiz": [88, 40, 94],
"test": [75, 90]
},
"totals": {}
"averages": {}
}
}
一旦你有了这个,你就不必测试你是否有一个字符串或数字作为值:
def eachSubjAverage(student):
for subject, marks in student["marks"].items():
total = sum(marks) #totalling each marks
student["totals"][subject] = total
average = total / (len(marks))
student["averages"][subject] = average
请注意,您可以以不同方式布置数据,即每个主题:
student1 = {
"personal_infos" : {
"name": "Lloyd",
},
"subjects": {
"homework": {
"marks" : [90, 97, 75, 92],
"total" : None,
"average" : None
},
"quiz": {
"marks" : [88, 40, 94],
"total" : None,
"average" : None
},
"test": {
"marks" : [75, 90],
"total" : None,
"average" : None
},
},
}
def eachSubjAverage(student):
for subject, data in student["subjects"].items():
total = sum(data["marks"]) #totalling each marks
data["total"] = total
average = total / (len(data["marks"]))
data["average"] = average
请注意,如果您没有修复数据结构(外部数据或其他)的选项,您仍然不想依赖类型检查(这充其量是脆弱的)-您想通过将主题名称列入白名单或将 "non-subjects" 名称列入黑名单来测试密钥本身,即:
# blacklist non-subjects
NON_SUBJECTS = ("name",)
def your_func(student):
for key, value in student.items():
if key in NON_SUBJECTS:
continue
compute_stuff_here()
哦,是的:在分数列表中添加总分和平均值也是搬起石头砸自己脚的好方法 - 一旦完成,您就无法判断最后两个 "marks" 是否是分数或(总计,平均)。
有几种方法可以检查数据的值。 try/except
结构看起来很笨重,但还有更短的方法。
首先你可以使用函数 type
,你 returns 类型的对象:
>>> type(student1['name']) == str
True
>>> type(student1['test']) == list
True
或者,使用一个非常简单的技巧。将任何对象乘以零 returns 空对象或 0 如果 int
:
>>> student1['name']*0 == ""
True
>>> student1['test']*0 == []
True
>>> student1['test'][1]*0 == 0
True
我正在创建一个函数来将每个数组(家庭作业、测验、测试)的标记添加到一个对象(student1)中。当代码尝试添加 "Lloyd" 时,肯定会出现错误。 我想查看"name"的value的data-type,只有当[=14= key 的 ]value 是数字。请建议。
student1 = {
"name": "Lloyd",
"homework": [90, 97, 75, 92],
"quiz": [88, 40, 94],
"test": [75, 90]
}
def eachSubjAverage(std):
for item in std:
total = sum(std[item]) #totalling each marks
std[item].append(total)
average_no = total/(len(std[item])-1) #averaging the marks
std[item].append(average_no)
eachSubjAverage(student1)
您可以检查该值是否可迭代:
hasattr(std[item], '__iter__')
然后检查每个成员是 Number:
all( map ( lambda x: isinstance(x,numbers.Number), std[item] ) )
您可以使用 try except
:
for item in std:
try:
total = sum(std[item])
except TypeError:
pass
for item in std:
if isinstance(std[item],list):
total = sum(std[item])
如果你想确保列表中的元素是int
类型,那么
for item in std:
if isinstance(std[item],list) and all(isinstance(e,int) for e in student1[item]):
total = sum(std[item])
了解 isinstance() 方法
一个明显的例子 XY problem...
您真正的问题是错误的数据结构以相同的方式存储异构信息(学生的姓名及其分数)。 RightSolution(tm)是使用更好的数据结构,即:
student1 = {
"personal_infos" : {
"name": "Lloyd",
},
"marks": {
"homework": [90, 97, 75, 92],
"quiz": [88, 40, 94],
"test": [75, 90]
},
"totals": {}
"averages": {}
}
}
一旦你有了这个,你就不必测试你是否有一个字符串或数字作为值:
def eachSubjAverage(student):
for subject, marks in student["marks"].items():
total = sum(marks) #totalling each marks
student["totals"][subject] = total
average = total / (len(marks))
student["averages"][subject] = average
请注意,您可以以不同方式布置数据,即每个主题:
student1 = {
"personal_infos" : {
"name": "Lloyd",
},
"subjects": {
"homework": {
"marks" : [90, 97, 75, 92],
"total" : None,
"average" : None
},
"quiz": {
"marks" : [88, 40, 94],
"total" : None,
"average" : None
},
"test": {
"marks" : [75, 90],
"total" : None,
"average" : None
},
},
}
def eachSubjAverage(student):
for subject, data in student["subjects"].items():
total = sum(data["marks"]) #totalling each marks
data["total"] = total
average = total / (len(data["marks"]))
data["average"] = average
请注意,如果您没有修复数据结构(外部数据或其他)的选项,您仍然不想依赖类型检查(这充其量是脆弱的)-您想通过将主题名称列入白名单或将 "non-subjects" 名称列入黑名单来测试密钥本身,即:
# blacklist non-subjects
NON_SUBJECTS = ("name",)
def your_func(student):
for key, value in student.items():
if key in NON_SUBJECTS:
continue
compute_stuff_here()
哦,是的:在分数列表中添加总分和平均值也是搬起石头砸自己脚的好方法 - 一旦完成,您就无法判断最后两个 "marks" 是否是分数或(总计,平均)。
有几种方法可以检查数据的值。 try/except
结构看起来很笨重,但还有更短的方法。
首先你可以使用函数 type
,你 returns 类型的对象:
>>> type(student1['name']) == str
True
>>> type(student1['test']) == list
True
或者,使用一个非常简单的技巧。将任何对象乘以零 returns 空对象或 0 如果 int
:
>>> student1['name']*0 == ""
True
>>> student1['test']*0 == []
True
>>> student1['test'][1]*0 == 0
True