蟒蛇尝试除了采取不同的行动

时间:2019-04-02 21:49:21

标签: python

我正在进行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')

2 个答案:

答案 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']

我测试了这些功能,只是试图为您列出的第一个词典模拟一个可能的“正结果”。 我不会再测试了

希望有帮助