列表索引超出范围错误在Json上循环

时间:2019-01-17 12:31:29

标签: python json django

我试图请求一个json对象,并使用for循环遍历该对象,并取出所需的数据并将其保存到Django中的模型中。

我只需要runner_1_namerunner_2_name的前两个属性,但是在我的json对象中,每个列表中的数量或流水线各不相同。我一直在获取列表索引超出范围错误。我尝试使用try and accept,但是当我尝试将其保存到模型时,它显示我的保存变量在赋值之前被引用了。忽略列表索引超出范围错误或固定列表以使索引正确的最佳方法是什么?我还希望代码能够真正快速运行,因为我将使用此功能作为每两秒钟轮询一次的后台任务。

@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()

2 个答案:

答案 0 :(得分:1)

快速修复:

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,因为您只是在期望块中传递,所以如果尝试失败,runner_1_namerunner_2_name永远不会定义。当您尝试使用这些变量时,会得到一个错误,因为它们从未定义过。因此,在except块中,将值设置为空白字符串或其他字符串,例如'Runner Does not Exists'


现在,如果您要完全避免使用try / except和IndexError,则可以使用if语句检查marketsrunners的长度。像这样的东西:

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捕获上面在我的第一个代码段中建议的任何错误。

答案 1 :(得分:0)

我遇到了一个问题列表,该列表可以为空,也可以由未知数量的评论填充

我的解决方案是将计数变量初始化为0,并在布尔值上进行while循环 在循环中,如果除IndexError失败外,我尝试获取comment [count],我将布尔值设置为False以停止无限循环

count = 0
condition_continue = True

while condition_continue :
    try:
        detailsCommentDict = comments[count]
        ....
    except IndexError:
        # no comment at all or no more comment
        condition_continue = False