字典方法更改

在 Python 3 中,许多字典方法在行为上与 Python 2 完全不同,许多字体方法也被删除了:has_keyiter*view*都消失了。而不是已经长期弃用的 d.has_key(key),现在必须使用 key in d

在 Python 2 中,字典方法 keysvaluesitems 返回列表。在 Python 3 中,它们返回视图对象; 视图对象不是迭代器,它们有两种不同之处,即:

  • 它们有尺寸(可以使用 len 功能)
  • 它们可以多次迭代

此外,与迭代器一样,字典中的更改也会反映在视图对象中。

Python 2.7 已经从 Python 3 向后移植了这些方法; 它们可以作为 viewkeysviewvaluesviewitems 使用。要将 Python 2 代码转换为 Python 3 代码,相应的表单是:

  • Python 2 的 d.keys()d.values()d.items() 应改为 list(d.keys())list(d.values())list(d.items())
  • d.iterkeys()d.itervalues()d.iteritems() 应该改为 iter(d.keys()),甚至更好,iter(d); 分别是 iter(d.values())iter(d.items())
  • 最后 Python 2.7 方法调用 d.viewkeys()d.viewvalues()d.viewitems() 可以替换为 d.keys()d.values()d.items()

移植 Python 2 代码,迭代字典键,值或项目,同时改变它有时是棘手的。考虑:

d = {'a': 0, 'b': 1, 'c': 2, '!': 3}
for key in d.keys():
    if key.isalpha():
        del d[key]

代码看起来好像它在 Python 3 中的工作方式类似,但是 keys 方法返回一个视图对象,而不是列表,如果字典在迭代时改变大小,Python 3 代码将与 RuntimeError: dictionary changed size during iteration 一起崩溃。解决方案当然是正确编写 for key in list(d)

类似地,视图对象的行为与迭代器的行为不同:一个不能在它们上使用 next(),一个不能恢复迭代; 它会重新启动; 如果 Python 2 代码将 d.iterkeys()d.itervalues()d.iteritems() 的返回值传递给期望迭代器而不是迭代的方法,则 Python 3 中应该是 iter(d)iter(d.values())iter(d.items())