我有一个小文件读取例程,我只想要我有它的前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? -
答案 0 :(得分:6)
它们不是等价的,因为在你的while循环中,它的条件为row_index < 200
,它永远不会为假,因为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循环中看到的一样。
答案 1 :(得分:3)
更传统的编写循环的方式是:
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
的替代,而不是{{1}有必要手动逐步执行迭代器:
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
答案 2 :(得分:0)
在第二种情况下,你在while
循环中被永久一遍又一遍地追加同一行......
答案 3 :(得分:0)
它们不能等价,因为在第一个代码中,只有一个循环是迭代的(for循环),它在row_index的每次迭代中检查if-else语句。在第二个代码中,while循环是一个嵌套循环,其中没有达到条件(因为没有迭代row_index)。这使得它进入无限循环,通过给出内存错误。
答案 4 :(得分:0)
所以我很好奇什么会更快,并在VB.NET中做了一个简单的例子。我不知道我提出的代码是否存在逻辑错误,但是当只执行100000次循环时,while循环更快。
当拥有大量数据时,时间差异很大。
与主题无关但不知何故它适合IF vs 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