На прошлом занятии

  • Списки и операции над ними
  • индексы и срезы
  • вложенные циклы

План этого занятия

  • Строки: разбиение и некоторые другие операции
  • Чтение файлов

Разбиение строк

Мы уже видели, что разбить строку на символы можно с помощью функции list():

>>> string = "Hello"
>>> characters = list(string)

А как разбить строку на отдельные слова? Для этого у строки есть специальный метод .split(), который возвращает список подстрок:

>>> cities = 'Москва Санкт-Петербург Казань Тверь Иркутск'
>>> words = cities.split()
>>> print(words)
['Москва', 'Санкт-Петербург', 'Казань', 'Тверь', 'Иркутск']

По умолчанию .split() делит строку по пробелам, символам табуляции и переноса строки. Кроме того, при таком вызове .split(), в результирующий список не входят пустые строки.

Если указать строку в качестве аргумента .split(), то вместо пробельных символов разбиение будет проходить по этой строке.

>>> pancake = 'молоко,яйца,мука,сметана'
>>> pancake_ingredients = pancake.split(',')
>>> print(pancake_ingredients)
['молоко', 'яйца', 'мука', 'сметана']
>>> burger = "котлета, булочка, кетчуп, салат"
>>> # Здесь мы должны использовать разбиение по строке из двух символов:
... # запятой и пробелу, чтобы в начале полученных строк не осталось пробелов:
... buger_ingredients = burger.split(', ')
>>> print(burger_ingredients)
['котлета', 'булочка', 'кетчуп', 'салат']

Обратите внимание, что при ручном указании строки-разделителя, пустые строки не выбрасываются:

>>> coffee = 'арабика    робуста  либерика'
>>> varieties = coffee.split()
>>> print(varieties)
['арабика',    'робуста',  'либерика']
>>> splited_by_space = coffee.split(' ')
>>> print(splited_by_space)
['арабика', '', '', '', 'робуста', '', 'либерика']
>>> tea = 'black,white,,green'
>>> varieties = tea.split(',')
print(varieties)
['black', 'white', '', 'green']

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

Чтение происходит с помощью функции open(), которой необходимо передать строку с указанием имени файла, а точнее системного пути (подробнее см. далее):

>>> f = open('text.txt', encoding='utf-8')  # кодировка может быть и другой, но с UTF-8 работать приятнее
>>> text = f.read()  # Теперь весь текст из файла находится внутри переменной text
>>> f.close()

Обязательно нужно закрыть файл, это как помыть руки перед едой! Иначе другим программам операционная система может запретить доступ к этому файлу. Для того, чтобы не забывать закрывать файлы, придуман специальный блок-мойдодыр with, который сам закроет наш файл. Принято пользоваться именно им для работы с файлами.

>>> with open('text.txt', encoding='utf-8') as f:
...     text = f.read())   # по умолчанию .read() читает файл целиком
...     splited_text = text.split()    # список из слов, иногда с «прилипшими» знаками препинания

Вместо того, чтобы прочесть файл в одну большую строку, включающую символы переноса строки, можно прочесть его в список отдельных строк:

>>> with open('text.txt', encoding='utf-8') as f:
...     lines = f.readlines()   # список из строк, каждая, быть может кроме последней, заканчивается символом переноса строки
...
>>> with open('text.txt', encoding='utf-8') as f:
...     text = f.read()
# Выходим из блока with ... as, больше читать из файла нечего
...
>>> lines = text.splitlines()    # список из строк, символы перевода строки отброшены

Может быть полезно читать файл по одной строке. Это можно сделать в цикле for:

>>> with open('text.txt', encoding='utf-8') as f:
...     for line in f:  # здесь строки тоже заканчиваются на символ переноса строки
...         if line.endswith('\n'):
...             print('Строка кончается на символ переноса строки')
...         else:
...             print('Строка не заканчивается на символ переноса строки')
...         line = line.strip()    # удаляем пробельные символы, в том числе перенос строки, сначала и сконца строки
...         if not line.endswith('\n'):
...             print('Теперь переноса строки точно нет')
...         if line.startswith('Давным-давно'):    # проверяем не начинается ли строка с данной строки
...             print('И жили они долго и счастливо')
...         print(line.count(' '))    # считаем число пробелов в строке
...         for word in line.split():
...             word = word.replace('.', '')
...             if word.isupper() and len(word) > 1:    # слово написано заглавными буквами, .islower() - наоборот
...                 print(word, '- быть может аббревиатура?')

Пути к файлам

Выше в вызове open() указывалось имя файла. В этом случае, питон ищет файл с соответствующим именем в той же папке, где была запущена программа. Что же делать, если требуется взять файл из другой папки?

В этом случае нужно указать путь к файлу: строку, разделённую символами /. Например, если нужно взять файл text.txt, лежащий в папке folder, находящейся в той же папке, где запущена программа, то необходимо написать open('folder/text.txt'). Такие пути называются относительными.

Абсолютными называются пути, которые начинаются с имени тома (в Windows) или корневого каталога (в Unix подобных операционных системах). Например: ‘C:/Users/Anna/Desktop/dimploma.txt’` (Windows) или ‘/Users/anna/Desktop/diploma.txt’ (macOS).

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

C:/
  Users/
    Anna/
       python_scripts/
         fix_grammar.py    <- Этот файл мы запускаем из этой папки
         example.txt
       Desktop/
         diploma.txt
    Yuri/
       Desktop/
         diploma.txt

Тогда, если необходимо запустить fix_grammar.py и открыть в нем файл example.txt, то можно указать относительный путь example.txt или абсолютный путь C:/Users/Anna/python_scripts/example.txt. Если нужно открыть диплом Анны, то укажем C:/Users/Anna/Desktop/diploma.txt или ../Desktop/diploma.txt. Диплом Юрия: C:/Users/Yuri/Desktop/diploma.txt или ../../Yuri/Desktop/diploma.txt.

Пример. Удаление запятых

Пусть дан файл text.txt, требуется вывести содержащийся в нем текст предварительно удалив запятые.

>>> with open('text.txt') as f:
...     text = f.read()
... # Лучше не делать лишних операций пока файл открыт, а поскорее закрыть его
...
text = text.replace(',', '')    # заменяем одну подстроку на другую
print(text)

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

На чём можно потренироваться?

Предложения

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

Статистика

  • Посчитайте число гласных и согласных в тексте.
  • Посчитайте сколько раз в тексте встретился предлог «под» или любой другой.

Домашнее задание

Программа должна открывать файл с русским текстом в UTF-8 и сообщать про него следующую информацию (по вариантам):

  1. чему равно среднее число слов в строке;
  2. во сколько раз самая короткая строка короче самой длинной;
  3. во сколько раз слов длины 3 больше, чем слов длины 1 (если слов длины 1 нет вообще, программа должна об этом сообщить);
  4. какой процент от общего количества слов не оканчивается знаком препинания (можно взять только запятую и точку);
  5. какой процент слов имеет длину больше 10 символов;
  6. какой процент слов начинается с большой буквы;
  7. какой процент строк содержит больше 5 слов.

Выполните задание пройдя по ссылке в GitHub Classroom:


Улучшить эту страницу