Sur*_*ari 42 python dictionary infinite-loop
我正在尝试在Python中创建无限循环的各种方法(除了通常之外while True),并提出了这个想法:
x = {0: None}
for i in x:
del x[i]
x[i+1] = None # Value doesn't matter, so I set it to None
print(i)
Run Code Online (Sandbox Code Playgroud)
在纸面上,我找到了无限循环的方式:
+ 1将是具有None更新字典的值的新键.在我看来,这应该以一种无限循环的方式输出自然数:
0
1
2
3
4
5
.
.
.
Run Code Online (Sandbox Code Playgroud)
我认为这个想法很聪明,但是当我在Python 3.6上运行时,它会输出:
0
1
2
3
4
Run Code Online (Sandbox Code Playgroud)
是的,它在5次迭代后以某种方式停止了.显然,循环的代码块中没有基本条件或标记值,那么为什么Python只运行此代码5次?
ben*_*nvc 43
如果你在循环中改变它,则无法保证迭代所有dict条目.来自文档:
在字典中添加或删除条目时迭代视图可能会引发RuntimeError或无法迭代所有条目.
您可以创建一个"枚举"无限循环,类似于您最初使用的尝试itertools.count().例如:
from itertools import count
for i in count():
print(i)
# don't run this without some mechanism to break the loop, i.e.
# if i == 10:
# break
# OUTPUT
# 0
# 1
# 2
# ...and so on
Run Code Online (Sandbox Code Playgroud)
在这种情况下,像@benvc写的那样,这不能保证有效.但是如果你想知道为什么它在C-Python中有效:
一些插入后,C-Python实现会销毁dict对象并将其复制到内存中的新空间.它不关心删除.因此,当发生这种情况时,循环会注意到它并以异常为中断.
如果你想在这里阅读更多关于这个以及许多其他有趣的python内部的信息,请查看此链接.
https://github.com/satwikkansal/wtfpython#-modifying-a-dictionary-while-iterating-over-it
小智 5
我刚刚在python2和python3中测试了你的代码
python3 output
0,1,2,3,4
python2
0,1,2,3,4,5,6,7
Run Code Online (Sandbox Code Playgroud)
有一件事可能会发生.当您创建第一个键值时,字典中只分配了一定量的内存,当您删除键值时,我们不会分配任何内存或释放内存,而只是删除值.一旦使用了所有分配的内存,它就会退出.因为如果你在没有del的情况下运行,你将收到此错误
RuntimeError: dictionary changed size during iteration
Run Code Online (Sandbox Code Playgroud)
因此python为该键值创建了足够的内存以及更多内存,一旦用完,就不再为字典分配内存.