我已经看到了两种在Python中创建无限循环的方法:
while 1:
do_something()
while True:
do_something()
这些之间有什么区别吗?还有一个比另一个更蟒蛇?
答案 0 :(得分:43)
从根本上说无关紧要,这种细节并不会影响某些东西是否是“pythonic”。
如果您对琐事感兴趣,那么会有一些差异。
旨在在古代版本上运行的builtin boolean type didn't exist till Python 2.3代码往往使用while 1:
形式。例如,您将在标准库中看到它。
True和False内置函数not reserved words prior to Python 3因此可以分配给它,更改它们的值。这有助于上述情况,因为代码可以执行True = 1
以实现向后兼容,但这意味着每次使用时都需要在全局字典中查找名称True
。
由于上述限制,两个版本编译的字节码在Python 2中是不同的,因为对True
不能使用的常量整数进行优化。因为Python可以告诉编译1
时它总是非零,它会删除条件跳转并且根本不加载常量:
>>> import dis
>>> def while_1():
... while 1:
... pass
...
>>> def while_true():
... while True:
... pass
...
>>> dis.dis(while_1)
2 0 SETUP_LOOP 5 (to 8)
3 >> 3 JUMP_ABSOLUTE 3
6 POP_TOP
7 POP_BLOCK
>> 8 LOAD_CONST 0 (None)
11 RETURN_VALUE
>>> dis.dis(while_true)
2 0 SETUP_LOOP 12 (to 15)
>> 3 LOAD_GLOBAL 0 (True)
6 JUMP_IF_FALSE 4 (to 13)
9 POP_TOP
3 10 JUMP_ABSOLUTE 3
>> 13 POP_TOP
14 POP_BLOCK
>> 15 LOAD_CONST 0 (None)
18 RETURN_VALUE
因此,while True:
更容易阅读,while 1:
对旧版本的Python有点好处。由于你现在不太可能需要在Python 2.2上运行,或者需要担心循环的字节码数量,所以前者稍微好一点。
答案 1 :(得分:10)
最pythonic方式永远是最可读的方式。使用while True:
答案 2 :(得分:5)
这并不重要。既不是难以阅读或理解,但我个人总是使用while True
,这更加明确。
更一般地说,人们用Python编写的大量while-break循环可能是其他东西。有时我会看到人们写i = 0; while True: i += 1 ...
,可以用for i in itertools.count()
代替,while True: foo = fun() if foo is None: break
可以写for foo in iter(fun, None)
,这可以写成{{1}},这需要学习,但需要较少的样板和机会愚蠢的错误。
答案 3 :(得分:4)
都不是。
它们都意味着我必须扫描代码以查找break
,而不是能够在它所属的位置看到停止条件。
我试图尽可能地避免这种事情,如果不可能的话,让代码说出来就像这样:
while not found_answer:
check_number += 1
if check_number == 42:
found_answer = True
修改:上面的“避免”一词似乎不够明确。使用基本上无限的循环并将其从循环内的某个地方(使用break
)通常应该完全避免。有时这是不可能的。在这种情况下,我喜欢使用类似上面代码的东西,然而,仍然代表相同的概念 - 上面的代码只不过是妥协 - 但是在至少,我可以在开头显示循环的目的 - 就像我不会调用函数do_something_with_args(*args)
一样。
答案 4 :(得分:2)
我认为这主要是风格问题。两者都应该很容易理解为无限循环。
但是,我个人更喜欢第二种选择。这是因为它只需要很少的理解,特别是没有C背景的程序员。
答案 5 :(得分:2)
第一个版本也适用于那些尚未定义True
的早期版本。
答案 6 :(得分:2)
IMO第二个选项是明显的。
如果你可以摆脱while
并编写更紧凑的代码,那可能会更加pythonic。
例如:
# Get the even numbers in the range 1..10
# Version 1
l = []
n = 1
while 1:
if n % 2 == 0: l.append(n)
n += 1
if n > 10: break
print l
# Version 2
print [i for i in range(1, 11) if i % 2 == 0]
# Version 3
print range(2, 11, 2)
答案 7 :(得分:2)
如果您的算法假设在有限的时间内终止,我建议这样做,这总是比while True
更安全:
maxiter = 1000
for i in xrange(maxiter):
# your code
# on success:
break
else:
# that algorithm has not finished in maxiter steps! do something accordingly
答案 8 :(得分:1)
我认为第二个表达式更明确,因此更多pythonic。
答案 9 :(得分:0)
这只是一种风格问题,任何编程初学者都会理解这两种选择。
但第二个选项仅在True
未分配给False
时才有效,这在Python 3之前是可能的:
>>> True = False
>>> True
False
答案 10 :(得分:0)
更好的方法是“while True”,条件突破循环。