Обнаружение повторяющихся слов в тексте с помощью Python
Поиск повторяющихся слов в тексте на Python
Задача поиска повторяющихся слов возникает при анализе текстов, проверке уникальности контента, составлении облака тегов или выявлении ключевых терминов. Python предлагает несколько подходов, от простых циклов до использования специализированных библиотек. В статье рассмотрены различные варианты с примерами кода и указанием типичных проблем.
Основное эффективное решение: collections.Counter
from collections import Counter
import re
text = "Python - это мощный язык. Python используют для анализа данных."
words = re.findall(r'\b\w+\b', text.lower())
word_counts = Counter(words)
repeated = {word: count for word, count in word_counts.items() if count > 1}
print(repeated)повторение слов python (поиск повторяющихся слов в тексте на python)
{'python': 2, 'данных': 2}Этот метод быстро обрабатывает текст, автоматически подсчитывает частоту и позволяет отфильтровать слова, встречающиеся более одного раза. Преимущества: мало кода, высокая производительность, встроенная сортировка по ключам.
Как найти повторяющиеся слова без использования сторонних библиотек?
text = "кот собака кот попугай собака"
words = text.lower().split()
seen = {}
for w in words:
if w in seen:
seen[w] += 1
else:
seen[w] = 1
repeated = {w: c for w, c in seen.items() if c > 1}
print(repeated){'кот': 2, 'собака': 2}Проблемы: split() разделяет только по пробелам, не учитывает знаки препинания. Решение использовать регулярное выражение или удалить пунктуацию вручную. Типичная ошибка – потеря окончаний из-за регистра – решается вызовом .lower().
Каким образом организовать подсчёт с помощью словаря вручную?
text = "анализ данных, анализ текста - анализ."
words = text.lower().replace(',','').replace('-','').replace('.','').split()
word_count = {}
for w in words:
word_count[w] = word_count.get(w, 0) + 1
repeated = {k: v for k, v in word_count.items() if v > 1}
print(repeated){'анализ': 3}Проблема: необходимо перечислять все знаки препинания. Решение – использовать string.punctuation из модуля string. Типичная ошибка – не учитывать дефисы и апострофы внутри слов. Для сложных текстов лучше применять регулярные выражения.
Как учесть различные разделители и знаки препинания с помощью регулярных выражений?
import re
text = "Привет, мир! Мир - прекрасен. Привет?"
words = re.findall(r'[а-яёА-ЯЁa-zA-Z]+', text.lower())
from collections import Counter
cnt = Counter(words)
print([w for w in cnt if cnt[w] > 1])['привет', 'мир']
Проблемы: регулярное выражение может не захватывать слова с цифрами или Unicode-символами. Для кириллицы нужно использовать флаг re.UNICODE или явно указывать диапазоны. Типичная ошибка – забыть про знак + и получить пустые строки. Решение – шаблон r'\b\w+\b' с учётом локали.
Как обработать текст из файла, не загружая его целиком?
from collections import Counter
import re
word_counts = Counter()
with open('large_text.txt', 'r', encoding='utf-8') as f:
for line in f:
words = re.findall(r'\b\w+\b', line.lower())
word_counts.update(words)
repeated = {w: c for w, c in word_counts.items() if c > 1}
print(len(repeated), "повторяющихся слов найдено")(пример вывода) 1245 повторяющихся слов найдено
Проблемы: большие файлы могут содержать нестандартные кодировки. Решение - указать encoding. Типичная ошибка – забыть закрыть файл (но with это решает). Если файл слишком большой, Counter может занять много памяти – тогда рекомендуется использовать внешнюю сортировку или базу данных.
Что делать, если нужно учитывать стемминг или лемматизацию?
import nltk
from nltk.corpus import stopwords
from nltk.stem import SnowballStemmer
nltk.download('punkt')
nltk.download('stopwords')
stemmer = SnowballStemmer('russian')
text = "бежал бежать бегун бег"
tokens = nltk.word_tokenize(text.lower())
stems = [stemmer.stem(w) for w in tokens if w.isalpha()]
from collections import Counter
cnt = Counter(stems)
repeated = {w: c for w, c in cnt.items() if c > 1}
print(repeated){'бег': 4}Проблемы: nltk требует скачивания данных – без этого вызовет ошибку. Стемминг может объединять слова с разным значением. Лемматизация точнее, но медленнее. Типичная ошибка – не удалить стоп-слова перед подсчётом, что даст шум.
Расширенные примеры поиска повторяющихся слов
Пример 1: удаление стоп-слов перед подсчётом
from collections import Counter
import re
stop_words = {'и', 'в', 'на', 'с', 'по', 'для', 'а', 'но', 'или', 'из'}
text = "И в анализе данных на Python и в других языках часто используют словари."
words = re.findall(r'\b\w+\b', text.lower())
filtered = [w for w in words if w not in stop_words]
counts = Counter(filtered)
repeated = {w: c for w, c in counts.items() if c > 1}
print(repeated){'анализе': 2, 'данных': 2, 'python': 2, 'словари': 2}Пример 2: топ-10 самых частых повторяющихся слов
from collections import Counter
import re
text = """
Пример текста с множеством повторений. Повторения слов помогают выявить ключевые темы.
Чем больше повторений, тем важнее слово. Слово 'слово' повторяется много раз.
"""
words = re.findall(r'\b\w+\b', text.lower())
counts = Counter(words)
top_10 = counts.most_common(10)
print(top_10)[('слово', 3), ('повторений', 2), ('повторения', 2), ('пример', 1), ('текста', 1), ('множеством', 1), ('помогают', 1), ('выявить', 1), ('ключевые', 1), ('темы', 1)]Пример 3: поиск слов, повторяющихся ровно 3 раза
from collections import Counter
import re
text = "раз два три раз два три раз два три четыре"
words = re.findall(r'\w+', text.lower())
counts = Counter(words)
exactly_three = {w: c for w, c in counts.items() if c == 3}
print(exactly_three){'раз': 3, 'два': 3, 'три': 3}Пример 4: обработка с сохранением регистра (чувствительность к регистру)
from collections import Counter
text = "Python python PYTHON"
words = text.split() # без lower()
counts = Counter(words)
print(counts)Counter({'Python': 1, 'python': 1, 'PYTHON': 1})Если нужно считать одинаковыми, используйте .lower(). Если важно различать – оставьте как есть.
Пример 5: использование pandas для наглядной таблицы частот
import pandas as pd
import re
from collections import Counter
text = "слово1 слово2 слово1 слово3 слово2 слово2"
words = re.findall(r'\w+', text.lower())
counts = Counter(words)
df = pd.DataFrame(counts.items(), columns=['Word', 'Frequency'])
df = df[df['Frequency'] > 1] # только повторяющиеся
print(df.to_string(index=False))Word Frequency слово1 2 слово2 3
Пример 6: многопоточная обработка большого текстового файла
from collections import Counter
import re
from concurrent.futures import ThreadPoolExecutor
def process_chunk(chunk):
words = re.findall(r'\b\w+\b', chunk.lower())
return Counter(words)
with open('very_large.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
# разделяем на несколько частей
chunks = [''.join(lines[i:i+1000]) for i in range(0, len(lines), 1000)]
with ThreadPoolExecutor(max_workers=4) as executor:
counters = list(executor.map(process_chunk, chunks))
total = Counter()
for cnt in counters:
total.update(cnt)
repeated = {w: c for w, c in total.items() if c > 1}
print(f"Найдено {len(repeated)} повторяющихся слов")(пример вывода) Найдено 3421 повторяющихся слов