python⾥while1是什么意思_关于
python:“while1”和“whileTr。。。
我已经看到了两种在Python中创建⽆限循环的⽅法:
while 1:
do_something()
在线学习韩语while True:
do_something()
这些之间有什么区别吗? ⼀个⽐另⼀个更pythonic吗?
也许⽆限循环不是pythonic吗? (请参阅balpha)
从根本上讲,这并不重要,这样的细节并不会真正影响某些东西是否为" pythonic"。
但是,如果您对琐事感兴趣,则有⼀些区别。
内置的布尔类型直到Python 2.3才存在,因此原本打算在较早版本上运⾏的代码倾向于使⽤while 1:形式。例如,您将在标准库中看到它。
True和Fal内置不是Python 3之前的保留字,因此可以分配给它们,以更改其值。这对上述情况有帮助,因为代码可以做到True = 1以实现向后兼容,但是这意味着每次使⽤全局名称字典时都需要在全局字典中查找名称True。
as well as
由于上述限制,两个版本编译的字节码在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:很好的解释了为什么问题应该降到零以下。
我想指出的是,以我的拙见,做某事的最Python⽅式是不要为这样的细节烦恼。尽管该帖⼦绝对有趣且内容丰富,但我对此表⽰赞赏,但我坚持认为while True:更具Python风格。⾄少以我解释pythonic奇数词的⽅式,您的学习成绩可能会有所不同。
刚尝试做True = Fal,效果"如预期",有趣:)
如果您⾮常努⼒,仍可以在3.x中重新定义True。在3.0中,import builtins; builtins.__dict__[True] = 0可以做到;在3.3中,您必须有更多的创造⼒,但仍然有可能。如果情况变得更糟,您始终可以ctypes进⼊C API(或与其他实现等效)。有趣的是,编译器假定您⽆法做到,因此某些表达式将被编译出来,⽽另⼀些表达式将以实现/版本相关的⽅式使⽤您的新值。⽽且,如果您能很好地利⽤所有这些资源,则可能会找到更好的时间利⽤⽅式...
最Python的⽅式将永远是最易读的。使⽤while True:sampler
对于C程序员⽽⾔,最易读的是1:。
" while 1:"与" for(;;)" :-)完全不同
@nomemory:问题是关于" Pythonic"的,它与C程序员⼏乎没有关系。如果您希望C程序员能读懂某些东西,请使⽤C。
@ S.Lott:我想说的是可读性是⾮常相对的。
没关系。两者都不难理解,尽管我个⼈总是使⽤while True,这更加明确。
更⼀般⽽⾔,⼈们⽤Python编写的很多while-break循环可能是另⼀回事。有时我看到⼈们写i = 0; while True: i += 1 ...,可以⽤for i unt()代替,⽽⼈们写while True: foo = fun() if foo is None: break时,可以写成for foo in iter(fun, None),这需要学习,但需要更少的样板,也没有机会犯傻。
都不⾏
它们都意味着我必须扫描代码以查找break,⽽不是能够在其所属位置看到停⽌条件。
我尝试尽可能避免这种情况,如果不可能,请让代码这样说:
while not found_answer:
check_number += 1
borgiaif check_number == 42:
found_answer = True
fleshget
编辑:似乎上⾯的"避免"⼀词不够清楚。通常应该完全避免使⽤基本上⽆限的循环并将其从循环内的某个位置放置(使⽤break)。有时这是不可能的。在那种情况下,我喜欢使⽤类似上⾯的代码的东西,但是,它仍然表⽰相同的概念,上⾯的代码不过是⼀种折衷,但是⾄少,我可以像我⼀样在开始时就说明循环的⽬的不会调⽤函数do_something_with_args(*args)。
但是在您的代码中,您只需扫描代码中的found_answer = True。
我不认为这是可取的。通常使⽤break的原因是⽆法轻松或有效地表达停⽌条件。如果从字⾯上讲是使⽤像found_answer这样的变量,则必须扫描该变量⽽不是break-通常,您仍然需要continue⽽不是break才能使其退出循环。
@迈克·格雷厄姆:是的,我说我想完全避免这种情况。如果使⽤它,我会通过给布尔值⼀个名称来解释该循环停⽌的原因来使事情变得清晰(即可读)。
@Scott Griffiths:但是与True不同,not found_answer或not received_quit_command向代码读者讲了⼀些内容。
@balpha:那是⼀个公平的观点,但是当您真正需要的只是开始时的简单注释时,您不禁要引⼊⼀个新变量并添加⼀个额外的条件评估,以使循环的意图更加清楚,我感到不解。
@Scott Griffiths:...以及在break语句中。但是,是的,这可能是个问题。我喜欢在可能的地⽅使⽤函数和变量名作为"注释"。但是你的观点是正确的。⽆论如何,我的观点还是尝试做完全不同的事情。我真的不明⽩为什么我的答案不清楚。
如果您有⼀种算法可以在有限时间内终⽌,那么我建议您这样做,它总是⽐while True更安全:
maxiter = 1000
for i in xrange(maxiter):
# your code
# on success:
break
canada dayel:
# that algorithm has not finished in maxiter steps! do something accordingly
我在这⽅⾯不同意,并且有⼀所杰出的学校制定尽可能严格的标准。如果期望值是零,那么说" == 0"并且不要依赖" <= 1",因为为-1可能表⽰之前处理的完全⾮预期分⽀;否则,则为0。肯定会检测到⼀个⽆限循环,⽽其他代码仍然必须确保这⼀点。
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)
第⼀个版本也可以在尚未定义True的早期版本中使⽤。
在这⼀点上,为Python 3编程之后,⽆论如何仍然要保持向后兼容性。referee
我不知道哪个是不⽀持True的Python的最新版本?
weddingdressrefu我认为这主要是风格问题。两者都应该很容易理解为⽆限循环。
但是,我个⼈更喜欢第⼆种选择。这是因为它只需要花很少的时间就能理解,特别是对于没有C背景的程序员⽽⾔。我相信第⼆个表达式更明确,因此更Python化。
更好的⽅法是"有条件时退出循环"时为"真"。
这只是样式问题,任何编程初学者都可以理解这两种选择。
但是,第⼆个选项仅在未将True分配给Fal的情况下才有效,这在Python 3之前是可⾏的:
>>> True = Fal
>>> True
Fal
那是⼀个很好的观察,但是与其他开发⼈员⼀起在项⽬上执⾏此操作的任何⼈⼏乎肯定会被打败他们⼀⽣。
是的,这当然只是玩笑。