Необходимо написать программу, которая считывает текст из файла (в файле может быть больше одной строки) и выводит самое частое слово в этом тексте и через пробел то, сколько раз оно встретилось. Если таких слов несколько, вывести лексикографически первое (можно использовать оператор < для строк). Слова, написанные в разных регистрах, считаются одинаковыми.
Sample Input: abc a bCd bC AbC BC BCD bcd ABC Sample Output: abc 3
Пытался реализовать задачу разными методами, однако в итоге получается не то.
Пример кода:
lst = [] maX = {} with open("someinputfile.txt", 'r') as s: for line in s: lst.extend(line.split()) for i in lst: maX.update({i:lst.count(i)}) with open("outfile.txt", "w") as out: out.write(str(maX))
Необходимо считать i
в разных регистрах и обновить значения в словаре, по коду который в примере получится словарь {'AbC': 1, 'BC': 1, 'a': 1, 'BCD': 1, 'bcd': 1, 'abc': 1, 'ABC': 1, 'bC': 1, 'bCd': 1}
Подскажите, какими методами можно считывать строки в разных регистрах или возможные реализации данной задачи?
Используйте Counter
из collections
:
>>> from collections import Counter >>> l = 'abc a bCd bC AbC BC BCD bcd ABC'.split() >>> l ['abc', 'a', 'bCd', 'bC', 'AbC', 'BC', 'BCD', 'bcd', 'ABC'] >>> c = Counter(l) >>> c Counter({'AbC': 1, 'ABC': 1, 'bCd': 1, 'abc': 1, 'bcd': 1, 'a': 1, 'BCD': 1, 'BC': 1, 'bC': 1}) >>> for k, v in c.items(): ... k, v ... ('AbC', 1) ('ABC', 1) ('bCd', 1) ('abc', 1) ('bcd', 1) ('a', 1) ('BCD', 1) ('BC', 1) ('bC', 1) >>>
Код в вопросе уже подсчитывает частоту слов, разделённых пробелами, с учётом регистра (не эффективно и не идиоматично, но код должен работать).
Чтобы считать слова без учёта регистра достаточно вызвать line.casefold()
.
Чтобы учесть условие: «Если таких слов несколько, вывести лексикографически первое», имея словарь с частотами слов:
counter = {'bcd': 3, 'abc': 3, 'bc': 2, 'a': 1} max_count = max(counter.values()) print(*min(p for p in counter.items() if p[1] == max_count)) # -> abc 3
Сортировка здесь не нужна так как все пары просматриваются, чтобы найти самые популярные слова.
Вот полный пример кода, который выводит лексикографически-первое слово, из самых популярных слов во вводе без учёта регистра (top-word.py
):
#!/usr/bin/env python3 import fileinput from collections import Counter c = Counter(word for line in fileinput.input() for word in line.casefold().split()) max_count = max(c.values()) print(*min(p for p in c.items() if p[1] == max_count))
fileinput.input()
читает строки со стандартного ввода (stdin
) или из файлов, указанных в командной строке (argv
). collections.Counter()
подсчитывает частоту повторения полученных слов.
Пример использования:
$ top-word input-file.txt >output-file.txt
Q: Функция ‘*min’ что делает?
min()
функция находит минимум:
min(['abc', 'bcd']) == 'abc' # 'abc' < 'bcd'
*
(звёдочка) перед именем — это специальный оператор, который распаковывает возвращаемую min()
пару ('abc', 3)
и передает её в print()
функцию как отдельные параметры:
p = ['abc', 3] print(*p)
это тоже самое что:
p = ['abc', 3] print(p[0], p[1])
то есть просто:
print('abc', 3)
Q: И можно итог выразить не печатая, а записывать как ‘abc 3’ в файл?
Чтобы в файл записать, достаточно file
параметр указать:
with open(filename, 'w') as file: print('abc', 3, file=file)
В итоге получился такой код:
import fileinput from collections import Counter c = Counter(word for line in fileinput.input(files=('dataset_3363_3.txt')) for word in line.casefold().split()) max_count = max(c.values()) f1 = open("1.txt", "w+") print(*min(p for p in c.items() if p[1] == max_count), file = f1)