Заметки на полях:
файл открыт и не закрыт. На максимальную скорость не влияет, но если в будущем вы будете открывать много файлов, операционная система откажет вам в доступе из-за нехватки ресурсов;
readlines
почти никогда не нужен;
в коде нет сложения чисел. Как тогда вычислить сумму?
Первое решение. Файл обрабатывается последовательно: сумма будет посчитана даже если файл не лезет в оперативную память:
with open('data_2.txt') as f: # закроет файл за собой
s = 0
for line in f: # перебирает строки в файле
for word in line.split(): # перебирает слова в строке
s += int(word) # накапливает сумму
print(s)
Второе решение. Смешивать перебор чисел из файла и суммирование - плохо. Питон позволяет их разделить. И снова файл не загружается в память целиком:
def ints(f): # вход - файл, выход - последовательность чисел
for line in f: # строки из файла
for word in line.split(): # слова из строк
yield int(word) # волшебство
with open('data_2.txt') as f:
print(sum(ints(f))) # sum суммирует последовательность
Третье решение. Проход по файлу всё ещё смешан с функциональностью: слова превращаются в числа. Разделим:
def words(f): # вход - файл, выход - последовательность слов
for line in f: # строки из файла
for word in line.split(): # слова из строк
yield word # волшебство
with open('data_2.txt') as f:
print(sum(map(int, words(f)))) # map переводит слова в числа
# sum суммирует
Четвёртое решение. Конструкция for ...: yield ...
упрощается до yield from ...
:
def words(f): # вход - файл, выход - последовательность слов
for line in f: # строки из файла
yield from line.split() # слова из строк и волшебство
Пятое решение. words
- функция-генератор. Можно сделать её обычной функцией, которая вернёт выражение-генератор. Ещё раз напомню, что генераторы не читают файл целиком в память. По прежнему в памяти только одна последняя прочитанная строка:
def words(f):
return (word for line in f for word in line.split())
Шестое решение. Раз всё свелось к выражению генератору, то и функция не нужна:
with open('data_2.txt') as f:
print(sum(map(int, (word for line in f for word in line.split()))))
Седьмое решение. map
не нужен, получается даже короче:
with open('data_2.txt') as f:
print(sum(int(word) for line in f for word in line.split()))
Восьмое решение. Всё по частям: отдельно читаются слова, отдельно переводятся в числа, отдельно суммируются:
def words(f): # функция-генератор
for line in f:
yield from line.split()
def ints(f): # обычная функция, возвращающая генератор
return map(int, words(f))
with open('data_2.txt') as f:
# напечатай(сумму(целых(из файла)))
print(sum(ints(f)))
Восемь разных решений - одна суть: файл не читается в память целиком, генераторы обрабатывают данные по мере поступления.