Питон Если против В то время как? - PullRequest
2 голосов
/ 19 апреля 2011

У меня есть процедура чтения небольшого файла, и я хочу, чтобы только первые 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

Этот код выполняется до тех пор, пока он не завершится с ошибкой из-за нехватки памяти. Я бы подумал, что это эквивалентно?в то время как?-

Ответы [ 5 ]

6 голосов
/ 19 апреля 2011

Они не эквивалентны, потому что в вашем цикле 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.

3 голосов
/ 19 апреля 2011

Более традиционный способ записи этого цикла:

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))
0 голосов
/ 14 апреля 2016

Поэтому мне было любопытно, что будет быстрее, и я сделал быстрый пример в 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
0 голосов
/ 19 апреля 2011

Они не могут быть эквивалентными, потому что в вашем первом коде повторяется только один цикл (цикл for), который проверяет операторы if-else на каждой итерации row_index.Во втором коде цикл while является вложенным циклом, в котором условие не достигается (поскольку нет ничего повторяющегося по row_index).это заставляет его идти в бесконечный цикл, давая ошибку памяти.

0 голосов
/ 19 апреля 2011

Во втором случае вы застряли навсегда в цикле while, добавляя одну и ту же строку снова и снова ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...