列表索引超出范围(使用json)

时间:2017-08-07 17:34:48

标签: python json

我导入了json并按名称过滤了它。

def lootprice(json_object, name):
    needobj = [obj for obj in json_object if obj['name'] == name][0]
    if needobj['have'] < needobj['max']:
        return needobj['price']

它有效,但显示出这种错误:

needobj = [obj for obj in json_object if obj['name'] == name][0] 
     

IndexError:列表索引超出范围

3 个答案:

答案 0 :(得分:1)

[obj for jj_object中的obj如果obj [&#39; name&#39;] == name]返回空,这意味着json_object中没有搜索到的名称。您应该捕获该异常并相应地返回一些内容。

def lootprice(json_object, name):
    try:
        needobj = [obj for obj in json_object if obj['name'] == name][0]
    except IndexError:
        # Return something that tells the user no results where found
        return None
    if needobj['have'] < needobj['max']:
        return needobj['price']

这里有完整的例子:

def lootprice(json_object, name):
    try:
        needobj = [obj for obj in json_object if obj['name'] == name][0]
    except IndexError:
        return None
    if needobj['have'] < needobj['max']:
        return needobj['price']

my_object = [
    {'obj_id': 1, 'name': 'test1', 'have': 12, 'max': 50, 'price': 11},
    {'obj_id': 2, 'name': 'test2', 'have': 12, 'max': 50, 'price': 22},
    {'obj_id': 4, 'name': 'test4', 'have': 12, 'max': 50, 'price': 44},
    {'obj_id': 5, 'name': 'test5', 'have': 12, 'max': 50, 'price': 55}
]

lootprice(my_object, 'test1') # Returns 11
lootprice(my_object, 'test2') # Returns 22
lootprice(my_object, 'test3') # Returns None
lootprice(my_object, 'test4') # Returns 44
lootprice(my_object, 'test5') # Returns 55

答案 1 :(得分:0)

您正在创建一个列表对象,获取第一个元素,然后将列表抛出到垃圾箱。如果这是一个活跃的网站,可能会变得昂贵。将列表理解放在生成器理解中(在parens而不是方括号内理解)并循环生成器将允许在找到第一个时提前返回。

def lootprice(json_object, name):
    for needobj in (obj for obj in json_object if obj['name'] == name):
        if needobj['have'] < needobj['max']:
            return needobj['price']
    # Return something that tells the user no results where found or,
    return None

现在,当满足“name”和“have max”条件时,就会发生返回。您可以将has-max条件移动到if条件中,但这可能会降低其可读性。如果没有过滤json_object中的“name”,则循环落到可以返回默认对象的出口,或者在此处编码,可以由调用者检查的None。调用者可以使用的默认对象但是表示没有找到任何内容将更加“pythonic”。

答案 2 :(得分:0)

我评论说试图引出一个事实,你应该得出结论,你需要一个if检查列表是否为空。您在第2行获得IndexError: list index out of range,因为您在尝试收到错误的情况下尝试索引到空列表。因此,我们需要定义一个变量price来携带一个默认值,如果我们有一个具有正确名称的json对象,则覆盖它。如果我们不这样做,我们将简单地返回该默认值,如果我们这样做,我们将执行您在原始代码中的正确处理。

def lootprice(json_object, name):
    # set this to whatever you want the default return to be when json_object doesn't have correct name
    price = None
    objects = [obj for obj in json_object if obj['name'] == name]
    # checks if it is not an empty array and proceeds to process
    if not objects:
        needobj = objects[0]
        if needobj['have'] < needobj['max']:
            price = needobj['price']
    return price