Как я могу использовать лямбду для подсчета количества слов в файле? - PullRequest
1 голос
/ 09 апреля 2020

Я пытаюсь вычислить количество слов в файле, используя reduce, lambda & readlines нетрадиционным способом:

import functools as ft
f=open("test_file.txt")
words=ft.reduce(lambda a,b:(len(a.split())+len(b.split())),f.readlines())
print(words)

Это вызывает ошибку атрибута, поскольку я ' Я пытаюсь разбить целые числа (индексы). Как мне получить этот код, чтобы разделить элементы итерируемого, возвращаемого f.readlines(), и последовательно добавить их длины (т. Е. Количество слов в этих строках), чтобы в конечном итоге вычислить общее количество слов в файле?

1 Ответ

2 голосов
/ 09 апреля 2020

Если вы пытаетесь получить количество слов в файле, f.read() имеет больше смысла, чем f.readlines(), поскольку устраняет необходимость суммировать построчное число. Вы получаете весь файл в чанке и затем можете разбить его на пустое пространство, используя split без аргументов.

>>> with open("foo.py") as f:
...     len(f.read().split())
...
1530

Если вы действительно хотите использовать readlines, проще избежать functools.reduce в любом случае и sum длины split строк (sum - очень краткая операция сокращения на итерируемой, которая избавляет от отвлекающего накопителя):

>>> with open("foo.py") as f:
...     sum(len(x.split()) for x in f.readlines())
...
1530

Хорошей практикой является использование with менеджер контекста, поэтому ваш ресурс автоматически закрывается. Используйте пробелы вокруг всех операторов, чтобы код был читабельным.

Что касается работы functools.reduce: он принимает лямбду, которая принимает аккумулятор в качестве первого аргумента и текущий элемент в качестве второго. Второй аргумент functools.reduce является итеративным, а третий инициализирует аккумулятор. Оставляя это поле пустым, вы устанавливаете значение первого элемента в итерируемом - вероятно, не то, что вам нужно, поскольку идея состоит в том, чтобы выполнить числовое суммирование с помощью аккумулятора.

Вы можете использовать

>>> with open("foo.py") as f:
...     ft.reduce(lambda acc, line: len(line.split()) + acc, f.readlines(), 0)
...
1530

но это кажется мне довольно рубиново-голдбергским способом решения проблемы.

...