我正在进行REST API调用以填充我们所有设备的清单。该API返回多层嵌套字典+列表,其中某些类型的设备缺少某些键。
我正在尝试遍历整个清单,并将每个值存储在列表中,如果找不到,则存储为“ n / a”。如果该设备的字典中不包含特定键,则代码将引发异常。这些列表将用于创建熊猫df。
我最终使用了多个try-except块,因为我需要根据导致异常的行进行不同的操作。有更有效的方法吗?
def populate_list(device_id, device_model, device_sn, result):
for items in result:
try:
device_id.append(items['inventoryDetailsDTO']['@id'])
except:
device_id.append('n/a')
try:
device_model.append(items['inventoryDetailsDTO']['summary']['deviceType'])
except:
device_model.append('n/a')
try:
device_sn.append(items['inventoryDetailsDTO']['chassis']['chassis'][0]['serialNr'])
except:
device_sn.append('n/a')
答案 0 :(得分:1)
也许您可以将逻辑包含在方法中。参见下面的示例:
def get_value(source, keys):
value = 'n/a'
try:
x = source[0]
for idx in range(1, len(keys)):
x = x[keys[idx]]
value = x
except:
print("Failed to retrieve value - will return {}".format(value))
return value
def populate_list(device_id, device_model, device_sn, result):
for items in result:
device_id.append(get_value(items, ['inventoryDetailsDTO','@id']))
device_model.append(get_value(items, ['inventoryDetailsDTO', 'summary', 'deviceType']))
device_sn.append(get_value(items, ['inventoryDetailsDTO', 'chassis', 'chassis', 0, 'serialNr']))
答案 1 :(得分:0)
我现在很fk;稍后我将添加更完整的答案。 综合:尝试查看将异常声明为car是否方便
Try:
my_code_to_check
Except (ExceptionName, AnotherExceptionName,...) as e:
"""Perform actions"""
尝试检查一下是否可以为每个异常获取一个var和/或为每个可能的错误获取一个if语句(或dict + get方法)
更新: 抱歉,我在开车,我的回复确实与主题无关。 现在我做了一些“实验”:
import time
#orignal method
def populate_list(device_id, device_model, device_sn, result):
for items in result:
try:
device_id.append(items['inventoryDetailsDTO']['@id'])
except:
device_id.append('n/a')
try:
device_model.append(items['inventoryDetailsDTO']['summary']['deviceType'])
except:
device_model.append('n/a')
try:
device_sn.append(items['inventoryDetailsDTO']['chassis']['chassis'][0]['serialNr'])
except:
device_sn.append('n/a')
return device_id, device_model, device_sn
# second method
def get_value(source, keys):
value = 'n/a'
try:
x = source[0]
for idx in range(1, len(keys)):
x = x[keys[idx]]
value = x
except KeyError:
print("Failed to retrieve value - will return {}".format(value))
return value
def populate_list_2(device_id, device_model, device_sn, result):
for items in result:
device_id.append(get_value(items, ['inventoryDetailsDTO', '@id']))
device_model.append(get_value(items, ['inventoryDetailsDTO', 'summary', 'deviceType']))
device_sn.append(get_value(items, ['inventoryDetailsDTO', 'chassis', 'chassis', 0, 'serialNr']))
return device_id, device_model, device_sn
#third method
def populate_list_3(device_id, device_model, device_sn, result):
for items in result:
device_id.append(items.get('inventoryDetailsDTO', {}).get('@id', "n/a"))
device_model.append(items.get('inventoryDetailsDTO', {}).get('summary', {}).get('deviceType', "n/a"))
device_sn.append(items.get('inventoryDetailsDTO', {}).get('chassis', {}).get('chassis', {}).get(0, {}).get('serialNr', "n/a"))
return device_id, device_model, device_sn
if __name__ == "__main__":
d1 = {"inventoryDetailsDTO": {'@id': "got it"}, "casual": "a value", "foo": "april's foo"}
d2 = {"check": 2, "dunno": "wow", 4: 10}
d3 = {"check": 3, "dict": {"inside": {"another": "450909"}}}
list_of_dicts = [d1, d2, d3]
device_id = []
device_model = []
device_sn = []
start = time.time()
device_id, device_model, device_sn = populate_list(device_id, device_model, device_sn, list_of_dicts)
end = time.time()
print("first way")
print(end-start, "\nresult:", device_id, device_model, device_sn, "\n")
# reset and go with second method
d1 = {"inventoryDetailsDTO": {'@id': "got it"}, "casual": "a value", "foo": "april's foo"}
d2 = {"check": 2, "dunno": "wow", 4: 10}
d3 = {"check": 3, "dict": {"inside": {"another": "450909"}}}
list_of_dicts = [d1, d2, d3]
device_id = []
device_model = []
device_sn = []
start = time.time()
device_id, device_model, device_sn = populate_list_2(device_id, device_model, device_sn, list_of_dicts)
end = time.time()
print("second way")
print(end - start, "\nresult:", device_id, device_model, device_sn, "\n")
# reset and go with third way
d1 = {"inventoryDetailsDTO": {'@id': "got it"}, "casual": "a value", "foo": "april's foo"}
d2 = {"check": 2, "dunno": "wow", 4: 10}
d3 = {"check": 3, "dict": {"inside": {"another": "450909"}}}
list_of_dicts = [d1, d2, d3]
device_id = []
device_model = []
device_sn = []
start = time.time()
device_id, device_model, device_sn = populate_list_3(device_id, device_model, device_sn, list_of_dicts)
end = time.time()
print("third way")
print(end - start, "\nresult:", device_id, device_model, device_sn, "\n")
我实现了三种不同的方法,还跟踪了表演所需的时间。
结果如下:
第一种方式
4.0531158447265625e-06
['get it'] ['n / a'] ['n / a']
第二种方式
无法获取值-将返回n / a
无法获取值-将返回n / a
无法获取值-将返回n / a
1.4781951904296875e-05
['n / a'] ['n / a'] ['n / a']
第三种方式
2.86102294921875e-06->嵌套dict.get()方法的最佳速度
['get it'] ['n / a'] ['n / a']
我测试了这些功能,只是试图为您列出的第一个词典模拟一个可能的“正结果”。 我不会再测试了
希望有帮助