[英]Python If vs. While?
I have a small file read routine and I want only the 1st 200 records I have it working but along the way I could not figure out what was wrong with using the "while" construct. 我有一个小文件读取例程,我只想要我有它的前200条记录,但是我一直无法弄清楚使用“while”构造有什么问题。 This code works:
此代码有效:
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
This code runs until it fails with an out of memory condition I would have thought it was equivalent? 这段代码一直运行,直到它失败并出现内存不足的情况我认为它是等效的?
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
so what would be the right construct using while? 那么什么是正确的构造使用时? –
-
They are not equivalent because in your while loop, it has the condition of row_index < 200
, which will never be false because row_index
will never change while you are in that loop. 它们不是等价的,因为在你的while循环中,它具有
row_index < 200
的条件,它永远不会为false,因为row_index
在你进入该循环时永远不会改变。
This is why you are getting a memory conditional because you are probably running into an infinite loop. 这就是为什么你得到一个条件的内存,因为你可能遇到了无限循环。
You are essentially saying: 你基本上是这样说的:
Psuedo Code: Psuedo代码:
stay in block one as long as row_index < 200:
block_one:
rows.append(row)
goto block_one
You can see that row_index will never change, thus you are going to be in block_one forever. 你可以看到row_index永远不会改变,因此你将永远在block_one中。
Whereas the if statement has the following psuedo code: 而if语句具有以下伪代码:
if row_index < 200 goto block_one otherwise break:
block_one:
rows.append(row)
You can see that block_one
is not going back to itself, like you see in the while loop. 您可以看到
block_one
不会回归自身,就像您在while循环中看到的那样。
The more traditional way of writing that loop would be: 编写该循环的更传统方式是:
for row_index, row in enumerate(csv.DictReader(items_file, dialect='excel', delimiter='\t')):
if (row_index >= 200):
break
rows.append(row)
As soon as the row counter hits 200, we bail out of the loop. 一旦行计数器达到200,我们就会退出循环。
To use a while
loop instead of a for
loop (note that, as a looping construct, while
is an alternative to for
rather than to if
) it is necessary to step through the iterator manually: 使用
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)
All that said, there's actually a superior alternative to both of these options available in the itertools
module: 所有这一切,实际上是
itertools
模块中可用的这两个选项的优越替代方案:
from itertools import islice
itr = csv.DictReader(items_file, dialect='excel', delimiter='\t')
rows = list(islice(itr, 200))
So I was curious what would be faster and did a quick example in VB.NET. 所以我很好奇什么会更快,并在VB.NET中做了一个快速的例子。 I don't know if the code I came up with has a logical errors but when doing only 100000 loops the while loops is faster.
我不知道我提出的代码是否存在逻辑错误,但是当只执行100000次循环时,while循环更快。
When having large numbers of data the time difference is hugh. 当拥有大量数据时,时间差异很大。
Has nothing to do with the topic but somehow it fits the IF vs 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
循环,一遍又一遍地追加同一行......
They can't be equivalent because in your first code, only one loop is iterating (the for loop) which checks the if-else statements at each iteration of row_index. 它们不能等价,因为在第一个代码中,只有一个循环是迭代的(for循环),它在row_index的每次迭代中检查if-else语句。 In your second code, the while loop is a nested loop in which the condition isn't being reached (since there is nothing iterating the row_index).
在第二个代码中,while循环是一个嵌套循环,其中没有达到条件(因为没有迭代row_index)。 that makes it go into an infinite loop, there by giving the memory error.
这使得它进入无限循环,通过给出内存错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.