NPE*_*NPE 75 python dictionary
假设我们有一个Python字典d,我们就像这样迭代它:
for k,v in d.iteritems():
del d[f(k)] # remove some item
d[g(k)] = v # add a new item
Run Code Online (Sandbox Code Playgroud)
(f并且g只是一些黑盒转换.)
换句话说,我们尝试添加/删除项目,d同时使用迭代它iteritems.
这个定义得很好吗?你能提供一些参考来支持你的答案吗?
(如果它被破坏了,如何解决这个问题非常明显,所以这不是我追求的角度.)
Rap*_*rre 49
它在Python文档页面(对于Python 2.7)中明确提到过
使用
iteritems()而添加或删除字典条目可能会产生一种RuntimeError或无法遍历所有条目.
同样适用于Python 3.
同样适用于iter(d),d.iterkeys()而且d.itervalues(),我会尽力说它的确如此for k, v in d.items():(我不记得具体是什么for,但如果实现调用,我不会感到惊讶iter(d)).
unu*_*tbu 44
在环绕容器时更换容器(例如dict)可能不安全.所以del d[f(k)]可能不安全.如您所知,解决方法是使用d.items()(循环容器的独立副本)而不是d.iteritems()(使用相同的底层容器).
可以修改dict 的现有索引处的值,但是在新索引(例如d[g(k)]=v)处插入值可能不起作用.
mur*_*d99 22
你不能这样做,至少是这样d.iteritems().我试了一下,Python失败了
RuntimeError: dictionary changed size during iteration
Run Code Online (Sandbox Code Playgroud)
如果你改用d.items(),那就行了.
在Python 3中,d.items()是一个字典视图,就像d.iteritems()在Python 2中一样.要在Python 3中执行此操作,请改用d.copy().items().这将类似地允许我们迭代字典的副本,以避免修改我们正在迭代的数据结构.
以下代码显示这个定义不明确:
def f(x):
return x
def g(x):
return x+1
def h(x):
return x+10
try:
d = {1:"a", 2:"b", 3:"c"}
for k, v in d.iteritems():
del d[f(k)]
d[g(k)] = v+"x"
print d
except Exception as e:
print "Exception:", e
try:
d = {1:"a", 2:"b", 3:"c"}
for k, v in d.iteritems():
del d[f(k)]
d[h(k)] = v+"x"
print d
except Exception as e:
print "Exception:", e
Run Code Online (Sandbox Code Playgroud)
第一个示例调用g(k),并抛出异常(字典在迭代期间改变了大小).
第二个示例调用h(k)并且不抛出任何异常,但输出:
{21: 'axx', 22: 'bxx', 23: 'cxx'}
Run Code Online (Sandbox Code Playgroud)
看看代码,看起来是错的 - 我本来期望的是:
{11: 'ax', 12: 'bx', 13: 'cx'}
Run Code Online (Sandbox Code Playgroud)
我有一个包含Numpy数组的大型字典,因此@ murgatroid99建议的dict.copy()。keys()事情不可行(尽管它可以工作)。相反,我只是将keys_view转换为一个列表,并且效果很好(在Python 3.4中):
for item in list(dict_d.keys()):
temp = dict_d.pop(item)
dict_d['some_key'] = 1 # Some value
Run Code Online (Sandbox Code Playgroud)
我意识到这并没有像上面的答案那样深入到Python内部工作的哲学领域,但是它确实为所述问题提供了实用的解决方案。
| 归档时间: |
|
| 查看次数: |
60234 次 |
| 最近记录: |