為什麼要避免 while 循環? (Why avoid while loops?)


問題描述

為什麼要避免 while 循環? (Why avoid while loops?)

我對 Python 作為一種入門語言的研究大約有 2 週的時間。我在 Zed 的 “Learn Python the Hard Way” 中提出了一個觀點,他建議:

僅使用 while‑loop 來永久循環,這意味著可能絕不。這僅適用於 Python,其他語言是不同的。

我已經用谷歌搜索了所有內容,引用了我能找到的所有內容,但我在世界上找不到任何理由為什麼會這樣Python 中的約定。是什麼讓它與眾不同?

當我 10 年前放棄編程時,我在 VB 中工作,並且經常被告知要擺脫我的 For 循環並改用 While 循環。我是個黑客(就像我今天一樣,雖然當時我寫了很多代碼),所以我只是做了我被告知的事情而沒有質疑它。好吧,現在我在質疑它。這是速度問題嗎?只是為了避免無轉義的無限嗎?


參考解法

方法 1:

The advice seems poor to me. When you're iterating over some kind of collection, it is usually better to use one of Python's iteration tools, but that doesn't mean that while is always wrong. There are lots of cases where you're not iterating over any kind of collection.

For example:

def gcd(m, n):
    "Return the greatest common divisor of m and n."
    while n != 0:
        m, n = n, m % n
    return m

You could change this to:

def gcd(m, n):
    "Return the greatest common divisor of m and n."
    while True:
        if n == 0:
            return m
        m, n = n, m % n

but is that really an improvement? I think not.

方法 2:

It's because in the typical situation where you want to iterate, python can handle it for you. For example:

>>> mylist = [1,2,3,4,5,6,7]
>>> for item in mylist:
...     print item
... 
1
2
3
4
5
6
7

Similar example with a dictionary:

>>> mydict = {1:'a', 2:'b', 3:'c', 4:'d'}
>>> for key in mydict:
...     print "%d‑>%s" % (key, mydict[key])
... 
1‑>a
2‑>b
3‑>c
4‑>d

Using a while loop just isn't necessary in a lot of common usage scenarios (and is not "pythonic").


Here's one comparison from a mailing list post that I though was a good illustration, too:

> 2. I know Perl is different, but there's just no equivalent of while > ($line = <A_FILE>) { } ?

Python's 'for' loop has built‑in knowledge about "iterable" objects, and that includes files. Try using:

for line in file:
    ...

which should do the trick.

方法 3:

Python follows the philosophy of

There should be one‑‑ and preferably only one ‑‑obvious way to do it.

(see https://www.python.org/dev/peps/pep‑0020/ for details).

And in most cases there is a better way to do iterations in Python than using a while loop.

Additionally at least CPython optimizes other kinds of loops and iterations (I consider map and list comprehensions as kinds of iteration) better than while loops.

Example: https://www.python.org/doc/essays/list2str

Use intrinsic operations. An implied loop in map() is faster than an explicit for loop; a while loop with an explicit loop counter is even slower.

I have no explanation why you were told to use while loops instead of for loops in VB ‑ I think it normally leads neither to better readable nor to faster code there.

方法 4:

The general issue with while loops is that it is easy to overlook, or somehow skip the statement where the loop variable gets incremented. Even a C for‑loop can have this problem ‑ you can write for(int x=0; x<10;), although it is unlikely. But a Python for loop has no such problem, since it takes care of advancing the iterator for you. On the other hand, a while loop forces you to implement a never fail increment.

s = "ABCDEF"
i = 0
while (i < len(s)):
    if s[i] in "AEIOU":
        print s[i], 'is a vowel'
        i += 1

is an infinite loop as soon as you hit the first non‑vowel.

方法 5:

A while loop is a tool, nothing more. To use it or not use it is a matter of whether it's the right tool for the job, nothing more. You are right to question the advice, it's silly.

That being said, there are constructs in python that obviate the need for while loops some of the time. For example, list comprehensions do things one might ordinarily do with a while or for loop.

Use the right tool for the job, don't try to memorize and stick to a bunch of rules. The goal is to write code that a) works and b) is clear.

(by Random_PersonGareth ReeseldarerathisNubokPaulMcGBryan Oakley)

參考文件

  1. Why avoid while loops? (CC BY‑SA 3.0/4.0)

#Python






相關問題

如何從控制台中導入的文件中訪問變量的內容? (How do I access the contents of a variable from a file imported in a console?)

在 python 3.5 的輸入列表中添加美元符號、逗號和大括號 (Adding dollar signs, commas and curly brackets to input list in python 3.5)

為 KeyError 打印出奇怪的錯誤消息 (Strange error message printed out for KeyError)

django 1.9 中的 from django.views.generic.simple import direct_to_template 相當於什麼 (What is the equivalent of from django.views.generic.simple import direct_to_template in django 1.9)

查詢嵌入列表中的數組 (Querying for array in embedded list)

如何在 Python 中搜索子字符串是否在二進製文件中? (How to search if a substring is into a binary file in Python?)

為什麼要避免 while 循環? (Why avoid while loops?)

使用python的json模塊解析json請求 (Parse a json request using json module of python)

為什麼使用 py2app 模塊創建 mac 文件時出現錯誤? (Why i am getting Error when creating mac file using py2app module?)

當 python 線程在網絡調用(HTTPS)中並且發生上下文切換時會發生什麼? (What happens when the python thread is in network call(HTTPS) and the context switch happens?)

如何繪製一條帶斜率和一個點的線?Python (How to plot a line with slope and one point given? Python)

Pickle 找不到我不使用的模塊? (Pickle can't find module that I am not using?)







留言討論