Get:TypeError:'dict_values'对象在使用python 3.2.3时不支持索引

Jes*_*Pet 100 python python-3.x

这是我的代码:

{names[i]:d.values()[i] for i in range(len(names))}
Run Code Online (Sandbox Code Playgroud)

这在使用python 2.7.3时完全正常; 但是,当我使用python 3.2.3时,我收到一个错误说明'dict_values' object does not support indexing.如何修改代码以使其与3.2.3兼容?

and*_*ler 158

在Python 3中,dict.values()(和dict.keys()and一起dict.items())返回一个view而不是一个列表.请参阅此处的文档.因此,您需要将呼叫包裹dict.values()在呼叫中,list如下所示:

v = list(d.values())
{names[i]:v[i] for i in range(len(names))}
Run Code Online (Sandbox Code Playgroud)

  • 如果可以,您是否愿意解释python 在此决定背后的基本原理?从幼稚的角度来看,我没有看到为什么视图在这种特殊情况下不允许索引的任何原因。我认为在视图概念背后有一个更宏大的方案,它不涉及索引,但会很清楚一些。 (5认同)
  • 对于每个看这个的人来说,OP的代码是unpythonic - 在Python中我们避免索引(更慢,更丑).正确的方法是@ DavidRobinson的[答案](/sf/answers/1220217491/):`dict(zip(names,d.values()))`.当然,这段代码也依赖于按名称排序的值,但这并不能保证. (3认同)

Dav*_*son 13

更简单的代码版本是:

dict(zip(names, d.values()))
Run Code Online (Sandbox Code Playgroud)

如果要保持相同的结构,可以将其更改为:

vlst = list(d.values())
{names[i]: vlst[i] for i in range(len(names))}
Run Code Online (Sandbox Code Playgroud)

(你可以很容易地把list(d.values())理解放在理解之内vlst;这样做只是浪费,因为它每次都会重新生成列表).

  • 你能粘贴你正在使用的精确代码和你得到的错误吗? (2认同)

mar*_*eau 7

在Python 3中,该dict.values()方法返回一个字典视图对象,而不是像在Python 2中那样的列表.字典视图具有长度,可以迭代,并支持成员资格测试,但不支持索引.

要使代码在两个版本中都有效,您可以使用以下任一方法:

{names[i]:value for i,value in enumerate(d.values())}
Run Code Online (Sandbox Code Playgroud)

    要么

values = list(d.values())
{name:values[i] for i,name in enumerate(names)}
Run Code Online (Sandbox Code Playgroud)

到目前为止,在任一版本中执行相同操作的最简单,最快速的方法是:

dict(zip(names, d.values()))
Run Code Online (Sandbox Code Playgroud)

但请注意,所有这些方法都会为您提供根据实际内容而变化的结果d.为了解决这个问题,您可以使用OrderedDict,它会记住键首次插入其中的顺序,因此您可以依赖该values()方法返回的顺序.

  • 更新:请注意,在 Python 3.7+ 中,常规字典维护插入顺序,因此不需要使用“OrderedDict”。(实际上 CPython 3.6 中也是如此,但尚未正式发布,这意味着在其他实现中可能会有所不同)。 (2认同)