Опубликован: 14.06.2015 | Доступ: свободный | Студентов: 4653 / 500 | Длительность: 21:48:00
Авторские права: Creative Commons Attribution 3.0
Самостоятельная работа 7:

Файлы

< Самостоятельная работа 1 || Самостоятельная работа 7: 12

14.4. Чтение файлов

До тех пор, пока дескриптор файла не содержит данные, создадим конструкцию с оператором for, читая в цикле и увеличивая счетчик для каждой строки в файле.

>>> fhand = open('mbox.txt')
>>> count = 0
>>> for line in fhand:
count = count + 1
>>> print('Line Count:', count)
Line Count: 132045

Мы можем использовать дескриптор файла как последовательность в цикле for. Наш цикл считает количество строк в файле и выводит окончательное значение на экран. Грубый перевод цикла for на человеческий язык: "для каждой строки в файле, представленной файловым дескриптором, увеличить переменную count на единицу".

Причина, по которой функция open не читает весь файл, заключается в том, что файл может иметь гигабайты данных. Функция open занимает одинаковое количество времени, независимо от размера файла.

В случае, когда файл читается с использованием цикла for, Python заботится о разбиении данных в файле на отдельные строки, используя символ новой строки. Python читает каждую строку, используя новую строку, и включает новую строку, как последний символ в переменную line для каждой итерации цикла for.

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

Если вы знаете что, файл является относительно небольшим по сравнению с размером вашей оперативной памяти, вы можете прочитать весь файл в одну строку, используя метод read для дескриптора файла.

>>> fhand = open('mbox-short.txt')
>>> inp = fhand.read()
>>> print(len(inp))
94626
>>> print(inp[:20])
From stephen.marquar

В этом примере все содержимое (94626 символов) файла mbox-short.txt прочитано непосредственно в переменную inp. Мы воспользовались строковым срезом для печати 20 символов строки данных, хранящейся в inp.

Помните, что такой способ использования функции open возможен только, если файл данных будет удобно помещаться в оперативную память вашего компьютера, иначе используйте циклы for или while.

14.5. Поиск через файл

Когда вы ищете данные через файл, это очень общий шаблон чтения через файл, игнорируя большинство строк и обрабатывая строки, которые соответствуют определенному критерию. Мы можем объединить шаблон для чтения файла со строковыми методами, построив простой механизм поиска.

К примеру, если мы хотим прочитать файл и вывести на экран строки, которые начинаются с префикса "From:", мы можем воспользоваться строковым методом startswith, выбрав строки с желанным префиксом.

>>> fhand = open('mbox-short.txt')
>>> for line in fhand:
if line.startswith('From:') :
print(line)

Программа выполняется, получаем следующий результат:

From: stephen.marquard@uct.ac.za

From: louis@media.berkeley.edu

From: zqian@umich.edu

From: rjlowe@iupui.edu

From: zqian@umich.edu

From: rjlowe@iupui.edu
...

Мы получили желаемый результат. Но откуда пустые строки? Это результат невидимости символа новой строки. Каждая строка оканчивается новой строкой, т.к. функция print печатает строку из переменной line, которая включает новую строку и затем функция print добавляет другую новую строку, в результате мы наблюдаем эффект двойного пробела.

Мы могли бы использовать строковый срез, чтобы напечатать все, кроме последнего символа, но простой подход заключается в использовании метода rstrip, который удаляет пробелы в правой части строки следующим образом:

>>> for line in fhand:
         line = line.rstrip()
         if line.startswith('From:'):
             print(line)

Получим следующий результат:

From: stephen.marquard@uct.ac.za
From: louis@media.berkeley.edu
From: zqian@umich.edu
From: rjlowe@iupui.edu
From: zqian@umich.edu
...

Вы можете усложнить структуру поиска, воспользовавшись инструкцией continue. Основная идея поиска в цикле - вы ищете "интересные" строки и пропускаете "неинтересные". И когда находите интересную строку - выполняете с ней какие-то действия.

Мы можем построить цикл по следующему шаблону, пропуская неинтересные строки:

>>> for line in fhand:
           line = line.rstrip()
           if not line.startswith('From:'):
                continue
           print(line)

Вывод программы совпадает с предыдущим.

Мы можем использовать строковый метод find для имитации поиска в текстовом редакторе. Так как find ищет вхождения строки в другой строке и либо возвращает позицию строки или -1, если строка не найдена, мы можем написать следующий цикл, чтобы показать строки, которые содержат "@uct.ac.za" (то есть письма приходят из университета Кейптауна в Южной Африке):

>>> fhand = open('mbox-short.txt')
>>> for line in fhand:
          line = line.rstrip()
          if line.find('@uct.ac.za') == -1 :
               continue
          print(line)

Получили следующий результат:

From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008
X-Authentication-Warning: nakamura.uits.iupui.edu: apache set sender to 
stephen.marquard@uct.ac.za using -f
From: stephen.marquard@uct.ac.za
Author: stephen.marquard@uct.ac.za
From david.horwitz@uct.ac.za Fri Jan 4 07:02:32 2008
X-Authentication-Warning: nakamura.uits.iupui.edu: apache set sender to 
david.horwitz@uct.ac.za using -f
From: david.horwitz@uct.ac.za
Author: david.horwitz@uct.ac.za
r39753 | david.horwitz@uct.ac.za | 2008-01-04 13:05:51 +0200 (Fri, 04 Jan 
2008) | 1 line
From david.horwitz@uct.ac.za Fri Jan 4 06:08:27 2008
X-Authentication-Warning: nakamura.uits.iupui.edu: apache set sender to 
david.horwitz@uct.ac.za using -f
From: david.horwitz@uct.ac.za
...

< Самостоятельная работа 1 || Самостоятельная работа 7: 12
Ксения Шошина
Ксения Шошина

курс Программирование на Python

Илья Кизилов
Илья Кизилов

В лекции приводится программа для сортировки слов по их длинне. В коде ошибка. Я исправил так:

def sort_by_length(words):

words = words.split()

t = []

for word in words:

t.append((len(word), word))

t.sort(reverse=True)

res = []

for length, word in t:

res.append(word)

return res

print(sort_by_length(words))

 

Кто ещё как сделал?

 

Екатерина Малкова
Екатерина Малкова
Россия, г. Москва