“while 1”和“while True”之间有什么区别?

时间:2010-02-14 17:28:42

标签: python while-loop infinite-loop

我已经看到了两种在Python中创建无限循环的方法:

  1. while 1:
        do_something()
    
  2. while True:
        do_something()
    
  3. 这些之间有什么区别吗?还有一个比另一个更蟒蛇?

11 个答案:

答案 0 :(得分:43)

从根本上说无关紧要,这种细节并不会影响某些东西是否是“pythonic”。

如果您对琐事感兴趣,那么会有一些差异。

  1. 旨在在古代版本上运行的builtin boolean type didn't exist till Python 2.3代码往往使用while 1:形式。例如,您将在标准库中看到它。

  2. True和False内置函数not reserved words prior to Python 3因此可以分配给它,更改它们的值。这有助于上述情况,因为代码可以执行True = 1以实现向后兼容,但这意味着每次使用时都需要在全局字典中查找名称True

  3. 由于上述限制,两个版本编译的字节码在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
    
  4. 因此,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”,条件突破循环。