代码之家  ›  专栏  ›  技术社区  ›  tomoc4

JSON上循环的列表索引超出范围错误

  •  1
  • tomoc4  · 技术社区  · 6 年前

    我尝试请求一个JSON对象,并使用for循环运行该对象,然后取出我需要的数据并将其保存到django中的模型中。

    我只想要 runner_1_name runner_2_name 但在我的JSON对象中,每个列表中的数量或运行者是不同的。我总是让列表索引超出范围错误。我尝试过使用“尝试并接受”,但当我尝试保存到模型时,它会显示在分配之前引用了我的保存变量,忽略列表索引超出或范围错误或修复列表以使索引正确的最佳方法是什么?我还希望代码运行得非常快,因为我将使用此函数作为后台任务,每两秒钟进行一次轮询。

    @shared_task()
    def mb_get_events():
    mb = APIClient('username' , 'pass')
    tennis_events = mb.market_data.get_events()
    
    for data in tennis_events:
    id = data['id']
    event_name = data['name']
    
    sport_id = data['sport-id']
    start_time = data['start']
    is_ip = data['in-running-flag']
    
    par = data['event-participants']
    event_id = par[0]['event-id']
    
    cat_id = data['meta-tags'][0]['id']
    cat_name = data['meta-tags'][0]['name']
    cat_type = data['meta-tags'][0]['type']
    url_name = data['meta-tags'][0]['type']
    
    try:
        runner_1_name = data['markets'][0]['runners'][0]['name']
    except IndexError:
          pass
     try: 
        runner_2_name = data['markets'][0]['runners'][1]['name']
     except IndexError:
          pass
    
    run1_par_id = data['markets'][0]['runners'][0]['id']
    run2_par_id = data['markets'][0]['runners'][1]['id']
    
    run1_back_odds = data['markets'][0]['runners'][0]['prices'][0]['odds'] 
    run2_back_odds = data['markets'][0]['runners'][1]['prices'][0]['odds'] 
    run1_lay_odds = data['markets'][0]['runners'][0]['prices'][3]['odds'] 
    run2_lay_odds = data['markets'][0]['runners'][1]['prices'][3]['odds'] 
    
    te, created = MBEvent.objects.update_or_create(id=id)
    te.id = id
    te.event_name = event_name
    te.sport_id = sport_id
    te.start_time = start_time
    te.is_ip = is_ip
    te.event_id = event_id
    te.runner_1_name = runner_1_name
    te.runner_2_name = runner_2_name
    te.run1_back_odds = run1_back_odds
    te.run2_back_odds = run2_back_odds
    te.run1_lay_odds = run1_lay_odds
    te.run2_lay_odds = run2_lay_odds
    te.run1_par_id = run1_par_id
    te.run2_par_id = run2_par_id
    te.cat_id = cat_id
    te.cat_name = cat_name
    te.cat_type = cat_type
    te.url_name = url_name
    te.save()
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Vaibhav Vishal    6 年前

    快速修复:

    try:
        runner_1_name = data['markets'][0]['runners'][0]['name']
    except IndexError:
        runner_1_name = ''  # don't just pass here
    try: 
        runner_2_name = data['markets'][0]['runners'][1]['name']
    except IndexError:
      runner_2_name = ''
    

    它给你 variables is referenced before assignment 因为在Expect块中,您只是路过,所以如果尝试失败 runner_1_name runner_2_name 从未定义。当你试图使用这些变量时,你会得到一个错误,因为它们从未被定义过。所以在except块中,要么将值设置为空字符串,要么设置为类似于 'Runner Does not Exists' .


    现在,如果你想完全避免尝试/排除和 IndexError 你可以使用 if 要检查的语句长度 markets runners . 像这样:
    runner_1_name = ''
    runner_2_name = ''
    # Make sure markets exists in data and its length is greater than 0 and runners exists in first market
    if 'markets' in data and len(data['markets']) > 0 and 'runners' in data['market'][0]:
        runners = data['markets'][0]['runners']
        # get runner 1
        if len(runners) > 0 and `name` in runners[0]:
            runner_1_name = runners[0]['name']
        else:
            runner_1_name = 'Runner 1 does not exists'
        # get runner 2
        if len(runners) > 1 and `name` in runners[1]:
            runner_2_name = runners[1]['name']
        else:
            runner_2_name = 'Runner 2 does not exists'
    

    正如你所看到的,这个过程太长了,这不是推荐的方法。
    您应该假设数据是正确的,并尝试获取名称,然后使用try/except捕获上面在我的第一个代码片段中建议的任何错误。