【问题标题】:Why does Python handle a KeyError differently than an IndexError (in this case)?为什么 Python 处理 KeyError 与 IndexError 不同(在这种情况下)?
【发布时间】:2014-08-22 04:20:28
【问题描述】:

我尝试了一些不同的单行解决方案来解决仅在变量不存在时才定义变量的问题,并注意到 Python 处理字典和列表/元组的方式不同。这些错误似乎与我完全相似,所以我很困惑为什么会有差异。

字典键错误处理

existing_dict = {"spam": 1, "eggs": 2}
existing_dict["foo"] = existing_dict["foo"] if not KeyError else 3

返回{"spam": 1, "eggs": 2, "foo": 3}

请注意,我在左侧和右侧都引用了一个不存在的键; Python 在它出现的任何一个子句中处理 KeyError 都没有问题。

列表索引错误处理(也适用于元组)

existing_list = ["spam","eggs"]
existing_list[2] = existing_list[2] if not IndexError else ["foo"]

返回IndexError: list assignment index out of range

解决这个特定错误 (answer here) 一点也不难,但我很好奇为什么这些情况会有所不同。在这两种情况下,似乎在两个受让人/分配子句中都存在错误,并带有一个“如果不是”错误捕获。

【问题讨论】:

    标签: python keyerror


    【解决方案1】:

    这两种情况中,KeyErrorIndexError 只是类并且都是真的:

    >>> bool(KeyError)
    True
    >>> bool(IndexError)
    True
    

    所有类对象在 Python 中测试为真,请参阅 Truth Value Testing

    您不能使用条件表达式来测试异常;对于两个您的示例,else 值被选择总是,然后分配;您的测试完全等同于:

    existing_dict["foo"] = 3
    existing_list[2] = ["foo"]
    

    您将改用异常处理,或使用长度测试。

    异常是因为分配给列表索引在索引已经存在的情况下才有效:

    >>> empty = []
    >>> empty[0] = None
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    IndexError: list assignment index out of range
    

    这只是字典和列表工作方式的不同;您可以附加到的列表,这将增加索引的数量。你不能用字典来做到这一点(没有顺序),所以要添加一个新的键值对,你需要分配给它。另一方面,如果列表支持任意索引分配,那么介于两者之间的所有索引会发生什么情况?如果列表是 empty 但您分配给索引 42 怎么办?索引 0-41 会发生什么变化?

    使用try/except 捕获异常:

    try:
        existing_list[2] = "foo"
    except IndexError:
        existing.append('foo')
    

    这会替换索引 2 处的现有值,或者如果索引尚不存在则追加。

    您可以尝试测试长度:

    if len(existing_list) <= 3:
        existing_list.append('foo')
    

    只有在还没有至少 3 个元素时才会附加它。

    对于字典,测试键:

    if 'foo' not in existing_dict:
        existing_dict['foo'] = 3
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-22
      • 2020-03-13
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 2015-01-01
      相关资源
      最近更新 更多