我见过两种在 Python 中创建无限循环的方法:
while 1: do_something()
while True: do_something()
这些有什么区别吗?一个比另一个更pythonic吗?
我见过两种在 Python 中创建无限循环的方法:
while 1:
do_something()
while True:
do_something()
这些有什么区别吗?一个比另一个更pythonic吗?
从根本上说没关系,这些细节并不会真正影响某些东西是否是“pythonic”。
但是,如果您对琐事感兴趣,则存在一些差异。
内置布尔类型直到 Python 2.3 才存在,因此打算在古代版本上运行的代码倾向于使用这种while 1:
形式。例如,您会在标准库中看到它。
True 和 False 内置不是 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 上运行,或者需要担心循环的字节码计数,因此前者略胜一筹。
最pythonic的方式总是最易读的。采用while True:
这并不重要。两者都很难阅读或理解,尽管我个人总是使用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)
,这需要学习,但样板代码和犯愚蠢错误的机会较少。
两者都不。
它们都意味着我必须扫描代码以查找break
,而不是能够在它所属的位置看到停止条件。
我尽量避免这种事情,如果不可能,让代码自己说话:
while not found_answer:
check_number += 1
if check_number == 42:
found_answer = True
编辑:上面的“避免”这个词似乎不够清楚。通常应该完全避免使用基本上无限循环并将其从循环内的某个位置(使用break
)离开。有时这是不可能的。在这种情况下,我喜欢使用类似于上面代码的东西,然而,它仍然代表相同的概念—— 上面的代码只不过是一种妥协——但至少,我可以在一开始就说明循环的目的——就像我不会调用函数一样。do_something_with_args(*args)
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)
我认为这主要是风格问题。两者都应该很容易理解为无限循环。
但是,我个人更喜欢第二种选择。那是因为它只需要一个心理微步骤就可以理解,尤其是对于没有 C 背景的程序员。
第一个也适用于True
尚未定义的早期版本。
如果您有一个假设在有限时间内终止的算法,我会推荐这个,它总是比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
我相信第二个表达式更明确,因此更pythonic。
这只是风格问题,任何编程初学者都会理解这两种选择。
但是第二个选项只有True
在没有分配到时才有效False
,这在 Python 3 之前是可能的:
>>> True = False
>>> True
False
更好的方法是“while True”,有条件地跳出循环。