一、说明
对于python来说,是一个open性质的开发工具,因此,不断改进和提升、增强是无时无刻不在进行之中,因此,一些老的代码经常不能执行,需要重新修改。本篇针对字典“视图对象”的错误调用展开对字典“视图对象”的研究。
二、字典“视图对象”概念
字典视图对象 dict.keys()、dict.values() 和 dict.items() 返回的对象是视图对象。它们提供了字典条目的动态视图,这意味着当字典更改时,视图会反映这些更改。 字典视图可以迭代以生成各自的数据,并支持成员测试:
- len(dictview)
返回字典中的条目数。
- iter(dictview)
返回字典中键key、值value或项item(表示为 (key, value) 的元组)的迭代器。
键和值按插入顺序进行迭代. 这就可以生成 (value, key)
配对,这种配对用 zip()函数生成:
pairs = zip(d.values(), d.keys())
.
这个配对也可以用下述方法生成:
pairs = [(v, k) for (k, v) in d.items()]
.
注意点:
- 在字典中添加或删除条目时迭代视图可能会引发运行时错误或无法迭代所有条目。
- 3.7 版更改:字典顺序保证为插入顺序。
三、字典“视图对象”访问
3.1 x in dictview 访问
如果 x 在底层字典的键、值或项中,则返回 True(在后一种情况下,x 应该是(键,值)元组)。
3.2 早期的访问方法
在早期的python中,字典是支持顺序索引的。因此,在python执行语句:
{names[i]:d.values()[i] for i in range(len(names))}
d是一个字典,d.values()[i]是合法的。
但是,到python3.3以后,不支持字典的序号索引,因此这种表示不合法了。如果依然按照以上操作,会出现错误提示:
Get: TypeError: 'dict_values' object does not support indexing when using python 3.2.3
四、错误原因
在 Python 3 中,dict.values()(连同 dict.keys() 和 dict.items())返回一个视图,而不是一个列表。请参阅此处的文档Built-in Types — Python 3.11.3 documentation。
五、错误改出
将 { names[i]:d.values()[i] for i in range(len(names)) } 进行如下改变:
您需要将对 dict.values() 的调用包装在对 list 的调用中,如下所示:
v = list(d.values())
{names[i]:v[i] for i in range(len(names))}
这样才能正常工作。
六、再看个例子
def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
Optional arg random is a 0-argument function returning a random
float in [0.0, 1.0); by default, the standard random.random.
"""
randbelow = self._randbelow
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1) if random is None else int(random() * (i+1))
x[i], x[j] = x[j], x[i]
当我运行 shuffle 函数时,它会引发以下错误,这是为什么?TypeError: 'dict_keys' 对象不支持索引。
错误之处:
很明显,您将 d.keys() 传递给随机播放函数。可能这是用 python2.x 编写的(当 d.keys() 返回一个列表时)。在 python3.x 中,d.keys() 返回一个 dict_keys 对象,它的行为更像是一个集合而不是一个列表。因此,它不能被索引。
解决方案是将 list(d.keys())(或简单的 list(d))传递给 shuffle。