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

Python Json上循环的列表索引超出范围错误,python,json,django,Python,Json,Django,我试图请求一个json对象,并使用for循环遍历该对象,取出所需的数据并将其保存到django中的模型中 我只想要runner\u 1\u name和runner\u 2\u name的前两个属性,但在我的json对象中,每个列表中的runner数量不同。我不断获取列表索引超出范围错误。我曾尝试使用try和accept,但当我尝试保存到模型时,它会显示我的保存变量在赋值之前被引用。忽略列表索引或范围错误或修复列表以使索引正确的最佳方法是什么?我还希望代码运行得非常快,因为我将使用此函数作为后台任

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

我只想要
runner\u 1\u name
runner\u 2\u name
的前两个属性,但在我的json对象中,每个列表中的runner数量不同。我不断获取列表索引超出范围错误。我曾尝试使用try和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()

快速修复:

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 = ''
它在赋值之前引用变量,因为在expect块中,您刚刚通过,所以如果try失败,则永远不会定义
runner\u 1\u name
runner\u 2\u name
。当你试图使用这些变量时,你会得到一个错误,因为它们从未定义过。因此,在except块中,将值设置为空白字符串或其他字符串,如
“Runner不存在”


现在,如果您想完全避免使用try/except和
indexer
,您可以使用
if
语句检查
市场
跑步者
的长度。大概是这样的:

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

我遇到了注释列表的问题,这些注释可以是空的,也可以由未知数量的注释填充

我的解决方案是将计数变量初始化为0,并在布尔值上有一个while循环 在循环中,我尝试获取注释[count],如果它在Indexer上失败,我将布尔值设置为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  

你能解释清楚你的问题吗?您的代码太多,无法阅读,请发送有问题的特定部分。如果您也可以格式化代码,那就太好了。“现在还看不懂。”@Mohsen_Fatemi我在想一个更好的方法来处理列表索引输出或ranger错误。在变量
runner\u 1\u name
runner\u 2\u name
上,列表大小各不相同,我只想要runner列表中的前两个元素。你可以显示你json的
市场部分吗?给我发一行
网球事件
,这样我就可以帮助你感谢你的答案,如果我也要对“run1\u back”做同样的话哪一个是浮点数我如何存储异常?我已尝试运行代码,但遇到一个值错误,无法将字符串转换为float让我检查它。请将其设置为0,而不是空字符串(
'
)也不要像这样获取运行程序1和运行程序2数据,您应该创建一个函数,返回dict中运行程序的所有数据,然后传递运行程序[0]和运行程序[1]这项职能。这将把代码一分为二。您也可以在一行中更新或创建,然后使用
MBEvent.objects.update\u或\u create(**dict)
,只需确保在模型中正确实施唯一性即可。