为什么Python 3需要用list()包装dict.items?

Dew*_*wfy 44 python python-2to3 python-3.x

我正在使用Python 3.我刚刚安装了一个Python IDE,我对以下代码警告感到好奇:

features = { ... }
for k, v in features.items():
    print("%s=%s" % (k, v))
Run Code Online (Sandbox Code Playgroud)

警告是:"对于Python3支持应该看起来像...... list(features.items())"

http://docs.python.org/2/library/2to3.html#fixers上也提到了这一点

它还在对列表的调用中包含了dict.items(),dict.keys()和dict.values()的现有用法.

为什么这有必要?

Eri*_*got 44

您可以放心地忽略这个"额外预防措施"警告:即使没有list两个版本的Python,您的代码也可以正常工作.如果你需要一个列表(但事实并非如此),它将以不同的方式运行:事实上,它features.items()是Python 2中的列表,但是Python 3中的视图.当用作可迭代时,它们的工作方式相同,如示例所示.

现在,Python 2到Python 3的转换工具2to3在安全方面存在错误,并假设您在使用时确实需要一个列表dict.items().这可能不是这种情况(如问题所示),在这种情况下dict.items(),Python 3(无包装list)更好(更快,更少内存消耗,因为没有构建列表).

具体来说,这意味着Python 2代码可以显式迭代视图:( for k, v in features.viewitems()将在Python 3中转换2to3features.items()).看起来你的IDE认为代码是Python 2,因为你的for语句非常好,在Python 3中,因此不应该有关于Python 3支持的警告.

  • 注意:通常,如果循环修改了dict,忽略警告是不安全的。它在没有`list()`的Python 3上中断。 (3认同)

Fré*_*idi 37

在Python 2,方法items(),keys()以及values()用于"拍摄快照"的词典内容,并返回一个列表.这意味着如果在迭代列表时字典发生更改,则列表中的内容不会更改.

在Python 3中,这些方法返回一个视图对象,其内容随着字典的变化而动态变化.因此,为了使这些方法的结果上的迭代行为与先前版本保持一致,list()必须在Python 3中执行附加调用以"获取视图对象内容的快照".

  • @Dewfy,不是真的。视图对象本身是安全的,但是一旦您从视图对象创建迭代器并在循环中使用这些迭代器,则在源字典中添加或删除条目可能会导致错误或“未命中”的条目。该文档说,“在字典中添加或删除条目时迭代视图可能会引发RuntimeError或无法迭代所有条目”。 (2认同)

Ste*_*nes 6

Python 3返回一个字典视图对象而不是Python 2将返回的列表,并且您期望的某些运算符可能不正确 - 如果底层字典发生更改,View对象也会更改(可能在您迭代的代码中)这可能会导致一些不受欢迎的惊喜).