【问题标题】:If else is failing at the end and throwing key error - python [closed]如果 else 最后失败并抛出关键错误 - python [关闭]
【发布时间】:2020-10-10 19:38:41
【问题描述】:

这似乎以前运行良好,但突然间我的代码停止工作了。如果 else 都成功运行,但最后它会给出一个关键错误。

这里的数据来自一个名为 userdata 的 json。

这里是代码示例1:

if(userdata["id"] == "Stage1"):
    for j in range(len(userdata['Data'])):
        if(userdata['Data'][j]['user']==userName):
            address=str(processdata['Data'][j]['address'])
            addressInst = ''.join(filter(str.isalnum, address))
            print(addressInst)
        else:
            print('not available')

错误:

KeyError: 'user'

我从从 API 获得的 json 中获取用户名,然后我正在调用另一个 api 来更新其地址。我在这个 if 语句之后调用了另一个 API,但由于某些原因,我在这里隐藏了代码。

if(userdata['Data'][j]['user']==userName):

我能够成功调用 API,但最后我每次都收到上述错误,因此我的函数无法运行。

我实际上想避免 if else,谁能告诉我如何保存匹配的数据

userdata['Data'][j]['user']==userName

然后调用API相应地更新数据以避免错误?

【问题讨论】:

  • 您似乎已经知道您的字典不包含“用户”键。您没有包含任何有助于诊断原因的内容。我不确定你在寻找什么答案
  • KeyError 仅表示您正在使用 [] 访问数据中不存在的字典键。在这种情况下,dict userdata['Data'][j] 中没有“user”键。您确实应该小心检查代码中是否缺少键,并让您的代码在它们出现时执行其他操作。
  • 在现有键集中找不到映射(字典)键时引发KeyError,您正在尝试索引一个值,这就是它发生的原因
  • 有什么办法可以存储userdata['Data'][j]['user']==userName的json并避免其他情况?
  • 我不关心用户不匹配,我只需要匹配来自该 json 的用户数据

标签: python json pandas numpy python-requests


【解决方案1】:

您正在尝试访问 JSON 中不存在的密钥。如果key不存在,使用get返回默认值:

if(userdata["id"] == "Stage1"):
    for data in userdata['Data']:
        if (data.get('user') == userName):
            address = data.get('address', [])
            addressInst = ''.join(filter(str.isalnum, address))
            print(addressInst)
        else:
            print('Not available')

或者没有if ... else ...的更短版本:

if(userdata["id"] == "Stage1"):
    for data in filter(lambda d: d.get('user') == userName, userdata['Data']):
        address = data.get('address', [])
        addressInst = ''.join(filter(str.isalnum, address))
        print(addressInst)

它的作用如下:

  • filter 为 lambda 返回 True 的列表中的项目返回 迭代器
  • 如果在 d 中找不到密钥“用户”,d.get('user') 将返回 None 而不是出错。

除非您确定字典将包含一个键,否则最好调用aDict.get(key, defaultValue) 以避免错误。

【讨论】:

  • 嘿,你真棒。您的代码的第二个版本正是我所需要的,但您能提供一些解释吗?
  • 嘿,如何在 filter() 中添加另一个条件?
  • lambda d: (d.get('user') == userName) and (...)
  • 它接受“and”而不是“&”?
  • and 是逻辑与。 & 是按位与
【解决方案2】:

在比较未知字典中的值之前,我们应该始终检查键是否存在。我在处理 api 响应时遵循这一点。

你可以这样做:

if(userdata["id"] == "Stage1"):
    for j in range(len(userdata['Data'])):
        if 'user' in userdata['Data'][j].keys() and (userdata['Data'][j]['user']==userName):
            address=str(processdata['Data'][j]['address'])
            addressInst = ''.join(filter(str.isalnum, address))
            print(addressInst)
        else:
            print('Either the key user is not present or the values do not match.')

正如您之前所说的那样,它可以工作,而现在相同的代码却不行了。

这可能是由于 api 响应发生变化而发生的。之前它给出了一些不同的 JSOn 数据,现在它不同了。

【讨论】:

  • 这似乎对我有用,使用它后我不再得到错误,但你能告诉我是否可以将匹配的键值存储在另一个 json 中然后调用 api 吗?而不是使用 if else?
  • 我没看懂问题兄弟坦率地说。你能详细说明一下吗?什么 json 和什么匹配键值?
  • 嘿Prashant,请检查@Code Different 的第二个版本的答案,这是我想做的
  • 很高兴听到您的问题得到解决。他在理解您的 json 结构方面做得很好。干杯兄弟。
  • 感谢您的帮助。你的代码确实解决了我 90% 的问题
【解决方案3】:

为了避免在 API 上运行时算法停止,在请求失败的情况下,我使用了 try 语句,这里是一个例子。

a = [0, 1, 2]

for _ in a:
  print(1/_)

out:
error
1.0
0.5

没有 try 语句,算法会中断。

a = [0, 1, 2]

for _ in a:
  print(1/_)

out: 
ZeroDivisionError: division by zero

对每个请求都使用try,如果失败,您将不必重新启动。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 2022-01-16
    • 2015-06-06
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多