![](/img/trans.png)
[英]while (1) vs. while(True) — Why is there a difference (in python 2 bytecode)?
[英]Python If vs. While?
我有一個小文件讀取例程,我只想要我有它的前200條記錄,但是我一直無法弄清楚使用“while”構造有什么問題。 此代碼有效:
import csv, sys, zipfile
sys.argv[0] = "/home/tom/Documents/REdata/AllListing1RES.zip"
zip_file = zipfile.ZipFile(sys.argv[0])
items_file = zip_file.open('AllListing1RES.txt', 'rU')
rows = []
for row_index, row in enumerate(csv.DictReader(items_file, dialect='excel', delimiter='\t')):
if (row_index < 200):
rows.append(row)
else : break
這段代碼一直運行,直到它失敗並出現內存不足的情況我認為它是等效的?
import csv, sys, zipfile
sys.argv[0] = "/home/tom/Documents/REdata/AllListing1RES.zip"
zip_file = zipfile.ZipFile(sys.argv[0])
items_file = zip_file.open('AllListing1RES.txt', 'rU')
rows = []
for row_index, row in enumerate(csv.DictReader(items_file, dialect='excel', delimiter='\t')):
while (row_index < 200):
rows.append(row)
else : break
那么什么是正確的構造使用時? -
它們不是等價的,因為在你的while循環中,它具有row_index < 200
的條件,它永遠不會為false,因為row_index
在你進入該循環時永遠不會改變。
這就是為什么你得到一個條件的內存,因為你可能遇到了無限循環。
你基本上是這樣說的:
Psuedo代碼:
stay in block one as long as row_index < 200:
block_one:
rows.append(row)
goto block_one
你可以看到row_index永遠不會改變,因此你將永遠在block_one中。
而if語句具有以下偽代碼:
if row_index < 200 goto block_one otherwise break:
block_one:
rows.append(row)
您可以看到block_one
不會回歸自身,就像您在while循環中看到的那樣。
編寫該循環的更傳統方式是:
for row_index, row in enumerate(csv.DictReader(items_file, dialect='excel', delimiter='\t')):
if (row_index >= 200):
break
rows.append(row)
一旦行計數器達到200,我們就會退出循環。
使用while
循環而不是for
循環(注意,作為循環結構, while
是for
而不是if
的替代),有必要手動逐步執行迭代器:
itr = enumerate(csv.DictReader(items_file, dialect='excel', delimiter='\t'))
row_index = -1
while row_index < 199:
try:
row_index, row = next(itr) # Python 3. Use itr.next() in Python 2
except StopIteration:
break # Ran out of data
rows.append(row)
所有這一切,實際上是itertools
模塊中可用的這兩個選項的優越替代方案:
from itertools import islice
itr = csv.DictReader(items_file, dialect='excel', delimiter='\t')
rows = list(islice(itr, 200))
所以我很好奇什么會更快,並在VB.NET中做了一個快速的例子。 我不知道我提出的代碼是否存在邏輯錯誤,但是當只執行100000次循環時,while循環更快。
當擁有大量數據時,時間差異很大。
與主題無關但不知何故它適合IF與WHILE。
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim watch As New Stopwatch
Dim i As Integer = 0
For loops As Integer = 0 To 100000000
watch.Start()
If True Then
i += 1
End If
watch.Stop()
Next
MessageBox.Show(watch.ElapsedMilliseconds) ' 2740
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim watch As New Stopwatch
Dim loops As Integer = 0
watch.Start()
While loops < 100000000
loops += 1
End While
watch.Stop()
MessageBox.Show(watch.ElapsedMilliseconds) ' 300
End Sub
End Class
在第二種情況下,你永遠陷入了while
循環,一遍又一遍地追加同一行......
它們不能等價,因為在第一個代碼中,只有一個循環是迭代的(for循環),它在row_index的每次迭代中檢查if-else語句。 在第二個代碼中,while循環是一個嵌套循環,其中沒有達到條件(因為沒有迭代row_index)。 這使得它進入無限循環,通過給出內存錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.