嵌套json的Python测试-列表索引超出范围错误

嵌套json的Python测试-列表索引超出范围错误,python,Python,我试图查看boto3命令的输出中是否存在一个名为“AccessKeyId”的键 我得到这个错误: File "aws_iam_rotate_keys.py", line 76, in delete_access_key key2 = response['AccessKeyMetadata'][1]['AccessKeyId'] IndexError: list index out of range 这是生成错误的代码: user_name = str(input("Enter a

我试图查看boto3命令的输出中是否存在一个名为“AccessKeyId”的键

我得到这个错误:

  File "aws_iam_rotate_keys.py", line 76, in delete_access_key
    key2 =  response['AccessKeyMetadata'][1]['AccessKeyId']
IndexError: list index out of range
这是生成错误的代码:

user_name = str(input("Enter a user name: "))
paginator = client.get_paginator('list_access_keys')
for response in paginator.paginate(UserName=user_name):
    print("Raw response: ", response) 
    if 'AccessKeyId' and 'AccessKeyMetadata[0]':
        key1 =  response['AccessKeyMetadata'][0]['AccessKeyId']
        print("Key 1: ", key1)
    if 'AccessKeyId' and 'AccessKeyMetadata[1]':
        key2 =  response['AccessKeyMetadata'][1]['AccessKeyId']
这是“响应”的内容:

 {'AccessKeyMetadata': [{'UserName': 'bluethundr', 'AccessKeyId': 'AKIAJNYZQ2U5LGE6ZRWQ', 'Status': 'Active', 'CreateDate': datetime.datetime(2019, 3, 25, 17, 33, 40, tzinfo=tzutc())}], 'IsTruncated': False, 'ResponseMetadata': {'RequestId': '6b3e8952-4f27-11e9-af5a-356bad8d4700', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '6b3e8952-4f27-11e9-af5a-356bad8d4700', 'content-type': 'text/xml', 'content-length': '558', 'date': 'Mon, 25 Mar 2019 17:57:13 GMT'}, 'RetryAttempts': 0}}
我做错了什么?如果测试正确,我如何执行此操作

在此响应中,可以有一个或两个键。我想写一个包含这两种可能性的if测试

如果有两个键,则响应如下,代码不会中断:

 {'AccessKeyMetadata': [{'UserName': 'bluethundr', 'AccessKeyId': 'AKIAJNYZQ2U5LGE6ZRWQ', 'Status': 'Active', 'CreateDate': datetime.datetime(2019, 3, 25, 17, 33, 40, tzinfo=tzutc())}, {'UserName': 'bluethundr', 'AccessKeyId': 'AKIAJVNDVTUVFZHWSRSA', 'Status': 'Active', 'CreateDate': datetime.datetime(2019, 3, 25, 18, 8, 51, tzinfo=tzutc())}], 'IsTruncated': False, 'ResponseMetadata': {'RequestId': '16957e66-4f29-11e9-b7dc-7fcb6d606368', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': '16957e66-4f29-11e9-b7dc-7fcb6d606368', 'content-type': 'text/xml', 'content-length': '771', 'date': 'Mon, 25 Mar 2019 18:09:09 GMT'}, 'RetryAttempts': 0}}

在该响应中,
AccessKeyMetadata
是一个包含一项的列表,因此索引1超出范围。

您的if语句没有执行您认为它们正在执行的操作。 例如:

if 'AccessKeyMetadata'
应该是:

if response['AccessKeyMetadata']
你的支票

if 'AccessKeyId' and 'AccessKeyMetadata[0]':
是一种简单地测试这些常量字符串的检查。在控制台中运行此代码将返回:

>>> 'AccessKeyId' and 'AccessKeyMetadata[0]'
'AccessKeyMetadata[0]'
我想您应该改为测试响应对象:

# if response is a string and not yet parsed:
# response = json.loads(response)
# if it is already parsed, go on

# .get() with a default return value [] won't raise a KeyError
# or check with:
# if 'AccessKeyMetadata' in response
meta_data = response.get('AccessKeyMetadata', [])
if len(meta_data) == 1:
    key1 = meta_data[0].get('AccessKeyId', None)
elif len(meta_data) > 1:
    key2 = meta_data[1].get('AccessKeyId', None)

您在
if
子句中的检查有点混乱。您正在检查非空字符串,该字符串将始终返回
True

要使其尽可能接近您当前的代码,您应该这样做:

user\u name=str(输入(“输入用户名:”)
paginator=client.get\u paginator('list\u access\u keys'))
对于paginator.paginate(用户名=用户名)中的响应:
打印(“原始响应:”,响应)
如果len(响应['AccessKeyMetadata'])和响应['AccessKeyMetadata'][0]中的'AccessKeyId'
key1=响应['AccessKeyMetadata'][0]['AccessKeyId']
打印(“键1:,键1)
如果len(响应['AccessKeyMetadata']>1,并且响应['AccessKeyMetadata'][1]中的'AccessKeyId'
key2=响应['AccessKeyMetadata'][1]['AccessKeyId']

嗯,您的
AccessKeyMetaData
键似乎只有一个长度列表
1
,因此尝试访问索引
[1]
(即第二个索引)会给您一个
索引器
。。。然而,更大的问题是你的状况。你到底想测试什么?因为字符串
AccessKeyId
AccessKeyMetadata[1]
将始终对这两个字符串求值为
True
如果“AccessKeyId”和“AccessKeyMetadata[1]”
正在检查字符串的真实性?这样做的目的是什么?是的,我正在检查字符串的真实性。列表可以包含1个或2个键。它因用户而异。我需要编写一个测试,看看是否有1个或2个键。如果您试图测试
AccessKeyId
是否存在,您应该在响应['accesskeymata']时执行
if'AccessKeyId:
。如果要测试特定索引,则需要检查
响应['AccessKeyMetadata']
而不仅仅是字符串
'AccessKeyMetadata'
。你的代码没有做你认为它做的事情。任何时候,当您测试一个不是空字符串的字符串时,
'
,它的计算结果总是
True
。您应该根据您的数据而不是字符串进行测试!是的,我知道。列表可以包含一个或两个键。如何编写一个同时包含这两种可能性的测试?请查看列表的长度,如果列表的长度为1,请不要尝试访问第二项。@bluethundr很高兴能提供帮助!:)