簡體   English   中英

Python If vs. While?

[英]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循環(注意,作為循環結構, whilefor而不是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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM