Python, проверка файла данных на определенные строки

Я никогда не брал класс, в котором использовался python, только c, c++, c#, java и т. д. Это должно быть легко, но я чувствую, что мне не хватает чего-то огромного, на что реагирует python. Все, что я делаю, это читаю файл, проверяю строки, состоящие только из цифр, подсчитываю количество таких строк и отображаю их.

Итак, я открываю, читаю, чередую, проверяю isdigit() и увеличиваю. Что случилось?

# variables
sum = 0
switch = "run"

print( "Reading data.txt and counting..." )

# open the file
file = open( 'data.txt', 'r' )

# run through file, stripping lines and checking for numerics, incrementing sum when neeeded
while ( switch == "run" ):
    line = file.readline()
    line = line.strip()

    if ( line.isdigit() ):
        sum += 1

    if ( line == "" ):
        print( "End of file\ndata.txt contains %s lines of digits" %(sum) )
        switch = "stop"

person John Redyns    schedule 04.02.2011    source источник
comment
Ну, во-первых, ваш отступ кажется сломанным, но это, вероятно, только из-за форматирования. Какую ошибку вы получаете? И, кстати, отсутствие уроков в чем-то ничего не значит в этом мире.   -  person Matti Virkkunen    schedule 04.02.2011
comment
Отступ - это то, как это получилось здесь. С этим кодом он выводит 0 для суммы. А как насчет того, что я никогда раньше не изучал Python, лучше?   -  person John Redyns    schedule 04.02.2011
comment
Не уверен, что это проблема, но приведенный выше код останавливается, когда сталкивается с пробельной строкой.   -  person senderle    schedule 04.02.2011
comment
Можете ли вы предоставить образец строк в data.txt? Я попробовал код, и он сработал.   -  person Reiner Gerecke    schedule 04.02.2011
comment
sum — зарезервированное ключевое слово в Python. Пожалуйста, не используйте его!   -  person Seth Johnson    schedule 04.02.2011
comment
Я действительно не могу понять, почему он не работает, он продолжает возвращать 0.   -  person John Redyns    schedule 07.02.2011


Ответы (5)


Правильный способ в Python определить, достигли ли вы конца файла, это не видеть, возвращает ли он пустую строку.

Вместо этого выполните итерацию по всем строкам в файле, и цикл завершится, когда будет достигнут конец файла.

num_digits = 0
with open("data.txt") as f:
    for line in f:
        if line.strip().isdigit():
            num_digits += 1

Поскольку файлы можно перебирать, вы можете упростить это, используя выражение генератора:

with open("data.txt") as f:
   num_digits = sum( 1 for line in f if line.strip().isdigit() )

Я бы также рекомендовал не использовать зарезервированные ключевые слова Python, такие как sum, в качестве имен переменных, а также ужасно неэффективно использовать сравнение строк для логики потока, как вы делаете.

person Seth Johnson    schedule 04.02.2011

Я только что попробовал запустить ваш код:

matti@konata:~/tmp$ cat data.txt 
1
a
542
dfd
b
42
matti@konata:~/tmp$ python johnredyns.py 
Reading data.txt and counting...
End of file
data.txt contains 3 lines of digits

Здесь это работает нормально. Что у вас в data.txt?

person Matti Virkkunen    schedule 04.02.2011
comment
Вы пробовали это на файле со строкой пробела перед концом? - person senderle; 04.02.2011
comment
senderle: пробел в конце не должен иметь значения, но пробел в середине будет правильно подсчитывать только числа, идущие перед строкой, как указано в операторе if OP. - person Matti Virkkunen; 04.02.2011
comment
Думаю, я сомневаюсь, что это намерение ОП; в этом случае строка вывода должна читаться как End of file\ndata.txt contains %s lines of digits before the first line of whitespace - person senderle; 04.02.2011

Как сказали несколько человек, ваш код работает отлично. Возможно, ваш файл «data.txt» находится в другом каталоге, чем ваш текущий рабочий каталог (не обязательно в том каталоге, в котором находится ваш скрипт)?

Однако вот более "питоновский" способ сделать то же самое:

counter = 0
with open('data.txt', 'r') as infile:
    for line in infile:
        if line.strip().isdigit():
            counter += 1
print 'There are a total of {0} lines that start with digits'.format(counter)

Вы даже можете сделать это однострочным:

counter = sum([line.strip().isdigit() for line in open('data.txt', 'r')])

Хотя я бы сначала избегал этого маршрута... Он гораздо менее читабелен!

person Joe Kington    schedule 04.02.2011
comment
Быстрое примечание: вопрос заключался в том, чтобы подсчитать строки, состоящие только из цифр, а не те, которые начинаются с единицы. Просто вопрос удаления [0] в коде. - person Reiner Gerecke; 04.02.2011
comment
@squiddy Упс, совершенно верно! Я невнимательно прочитал, спасибо! По какой-то причине я прочитал вопрос как строки, начинающиеся с цифры... (Репост комментария, так как я случайно удалил его минуту назад...) - person Joe Kington; 04.02.2011

Как у вас работает программа? Вы уверены, что в data.txt есть данные? В файле есть пустая строка?

попробуй это:

while 1:
    line = file.readline()
    if not line: break
    line = line.strip()

    if ( line.isdigit() ):
        sum += 1


print( "End of file\ndata.txt contains %s lines of digits" %(sum) )
person Foo Bah    schedule 04.02.2011
comment
скобки не нужны для оператора if - person kurumi; 04.02.2011
comment
правда, но я просто скопировал и вставил из OP - person Foo Bah; 04.02.2011

person    schedule
comment
Программа OP дает сбой, когда в середине файла находится пустая строка. - person Foo Bah; 04.02.2011