0

我正在尝试一些不同的单行解决方案来解决仅在变量不存在时才定义变量的问题,并注意到 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

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

4

1 回答 1

5

这两种情况下, KeyErrorandIndexError只是类并且都是真的:

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

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

您不能使用条件表达式来测试异常;对于您的两个示例,总是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

这只是字典和列表工作方式的区别。您可以附加到的列表,这将增加索引的数量。你不能用字典来做到这一点(没有顺序),所以要添加一个新的键值对,你需要分配给它。另一方面,如果列表支持任意索引分配,那么介于两者之间的所有索引会发生什么?如果列表为但您分配给索引 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
于 2014-07-01T14:47:57.993 回答