making a new text from groups of words
которая соединяет некоторые группы из слов -> слов
в текст ии
эти группы слов находятся в файле
строки.txt
Хорошо — могу предложить несколько вариантов программы в Python в зависимости от того, в каком формате у вас файл строки.txt и как именно вы хотите "соединять группы слов". Ниже приведу 3 распространённых сценария и готовый код для каждого. Скажите, какой из них вам нужен, или пришлите пример файла (пару строк) — тогда адаптирую точнее.
Формат: каждая строка — группа слов, слова внутри группы разделены запятой (или другим разделителем). Задача: составить все возможные комбинации, беря по одному слову из каждой строки (декартово произведение). Результат: каждая комбинация — отдельная строка в выходном файле.
Пример строки.txt:
яблоко,груша
красный,зелёный
вилка,ложка
Код:
Python
Копировать код
import itertools
input_file = 'строки.txt'
output_file = 'output.txt'
sep = ',' # разделитель внутри строки
with open(input_file, 'r', encoding='utf-8') as f:
groups = []
for line in f:
parts = [p.strip() for p in line.strip().split(sep) if p.strip()]
if parts:
groups.append(parts)
if not groups:
print('Нет групп для обработки.')
else:
# Ограничение по количеству комбинаций (настраиваемое)
max_combinations = 1000000
total = 1
for g in groups:
total *= len(g)
if total > max_combinations:
break
if total > max_combinations:
raise SystemExit(f'Слишком много комбинаций: {total}. Уменьшите размер групп или установите больший лимит.')
with open(output_file, 'w', encoding='utf-8') as out:
for combo in itertools.product(*groups):
out.write(' '.join(combo) + '\n')
print(f'Создано {total} строк в {output_file}')
Формат: в каждой строке файла уже несколько слов — и нужно соединять слова внутри каждой строки в одно выражение (например, просто склеить через пробел), т.е. обработать каждую строку независимо.
Пример строки.txt:
быстрая коричневая лиса
перепрыгнула через ленивую собаку
Код:
Python
Копировать код
input_file = 'строки.txt'
output_file = 'output_simple.txt'
with open(input_file, 'r', encoding='utf-8') as f, open(output_file, 'w', encoding='utf-8') as out:
for line in f:
words = [w.strip() for w in line.strip().split() if w.strip()]
if words:
out.write(' '.join(words) + '\n')
print(f'Готово, сохранено в {output_file}')
Формат: каждая строка — группа, но нужно создавать комбинации не по всем строкам, а по заданным набором групп (например, только между строками 1,3,5), либо по шаблону (например: слово из группы1 + фиксированный текст + слово из группы2). Для этого можно задать индексы групп и/или шаблон-строку с плейсхолдерами.
Пример использования шаблона: шаблон "{0} и {1} — отличная пара", где {0} берётся из группы 1, {1} — из группы 2.
Код:
Python
Копировать код
import itertools
input_file = 'строки.txt'
output_file = 'output_template.txt'
sep = ','
# какие группы использовать (индексы с 0)
use_groups = [0, 1]
template = '{0} и {1} — отличная пара'
with open(input_file, 'r', encoding='utf-8') as f:
all_groups = []
for line in f:
parts = [p.strip() for p in line.strip().split(sep) if p.strip()]
all_groups.append(parts)
groups = [all_groups[i] for i in use_groups]
with open(output_file, 'w', encoding='utf-8') as out:
for combo in itertools.product(*groups):
out.write(template.format(*combo) + '\n')
print('Готово')
Дополнительные опции, которые могу добавить:
Параметры командной строки (argparse) для указания файлов, разделителя, шаблона, лимита комбинаций.
Удаление дубликатов, фильтры (по длине строки, по наличию подстроки).
Сохранение в CSV или JSON.
Генерация только случайной выборки из всех комбинаций (если комбинаций слишком много).
Скажите:
Какой формат у вашего строки.txt (покажите 3–5 строк) и какой именно желаемый результат (пример строк в выходном файле)?
Нужен ли графический интерфейс или достаточно скрипта для запуска в консоли?
Нужно ли ограничивать количество выводимых комбинаций или выбрать случайные?
мне нужно знать как это работает
возможно нам понадобится дополнительная информация
для этого мы можем изменить порядок слов в нашем тексте
чтобы изменить его содержание
или также контекст того что в нём написано
это может быть нам сделать не так и сложно
когда у нас есть исходный текст
из которого мы можем брать группы
из нескольких слов связанных по смыслу своим значением
Хорошо — опишу пошагово общую схему и варианты реализации: как из исходного текста получать группы слов по смыслу, как комбинировать их в новые предложения и как менять порядок/контекст, чтобы контролировать содержание. Приведу несколько практических подходов — от простого к более «умному» (семантическому) — и короткие примеры кода.
Общая идея (конвейер)
Подготовка исходного текста: разбить текст на строки/фразы/предложения.
Выделение «групп» слов: каждую группу составляют связанные по смыслу слова (например: синонимы, тематические наборы, сущности, ключевые фразы).
Хранение групп в файле (строки.txt): каждая строка — одна группа, элементы разделены разделителем (запятая/таб).
Генерация комбинаций: берём по одному элементу из разных групп (перестановки, декомпозиция по шаблону) и собираем новые фразы.
Постобработка: согласование формы слова, корректировка порядка, опциональная перефразировка/коррекция грамматики, фильтрация по семантике.
Как формировать группы (варианты)
Ручной способ: вы сами составляете строки.txt, каждая строка = группа. Просто и надежно, когда групп немного.
По шаблону/регулярным выражениям: если исходный текст структурирован, можно выбирать по regex.
По POS (части речи): извлечь существительные, прилагательные, глаголы из предложений (удобно для замены субъектов, действий, описаний).
NER (распознавание сущностей): выделить имена, места, даты и т.п.
Кластеризация по векторным эмбеддингам: получить векторное представление слов/фраз (word2vec, fastText, sentence-transformers) и кластеризовать по близости — группы по смыслу.
Синонимы и тезаурус: расширять группы синонимами (WordNet или модели).
Примеры задач и подходов
Собрать всё в шаблон: "X и Y — отличная пара" — берём X из группы1, Y из группы2.
Менять порядок слов: генерируем варианты порядка (перестановки) и/или применяем правила согласования (падежи, числа).
Изменять контекст/содержание: заменить ключевые слова на слова из другой группы (сохранить грамматику через соглашение форм или использовать модели для перефразирования).
Ограничить семантику: фильтровать комбинации по косинусной близости эмбеддингов к целевой теме.
Практическая реализация: простой скрипт (концепт)
Предположим файл строки.txt содержит группы по строкам и элементы разделены запятыми.
Генерация всех комбинаций через itertools.product, запись в файл, опциональный шаблон.
Код (упрощённо):
Python
import itertools
input_file = 'строки.txt' # каждая строка: слово1, слово2, ...
template = '{0} и {1} — отличная пара'
use_groups = [0, 1] # какие строки-файла использовать
# чтение групп
groups = []
with open(input_file, encoding='utf-8') as f:
for line in f:
parts = [p.strip() for p in line.strip().split(',') if p.strip()]
groups.append(parts)
selected = [groups[i] for i in use_groups]
# генерация комбинаций
with open('output.txt', 'w', encoding='utf-8') as out:
for combo in itertools.product(*selected):
out.write(template.format(*combo) + '\n')
Улучшение качества (грамматика и согласование)
Простейшие правила: хранить слова в начальной форме и при необходимости применять морфологию (pymorphy2 для русского) чтобы согласовать падеж/число.
Использовать spaCy/UDPipe для синтаксического анализа и корректных перестановок.
Для естественного звучания использовать модель перефразирования (например, transformer), чтобы переписать результат в грамматически корректной форме.
Пример использования pymorphy2 (для согласования):
Python
Копировать код
from pymorphy2 import MorphAnalyzer
m = MorphAnalyzer()
# пример: привести прилагательное к форме множественного числа именительного падежа
parsed = m.parse('большой')[0]
adj_form = parsed.inflect({'plur','nomn'}).word # 'большие'
Семантическая группировка (более продвинутый вариант)
Получить эмбеддинги фраз (sentence-transformers).
Кластеризовать (KMeans или DBSCAN) чтобы автоматом выделять тематические группы.
Примерный псевдокод:embeddings = model.encode(list_of_phrases)
clusters = KMeans(...).fit_predict(embeddings)
сохранить кластерные группы в файл.
Изменение порядка и контекста
Перестановки: itertools.permutations или просто менять индекс шаблона.
Добавление вводных фраз/контекстных маркеров (например, «согласно», «в результате», «на самом деле»), которые можно хранить в отдельной группе и вставлять.
Контекстуальная замена: если нужно поменять тон или подтекст, заменять ключевые лексические элементы на синонимичные, антонимичные или более нейтральные слова; можно применять эмбеддинги для поиска наиболее близких синонимов.
Ограничение количества комбинаций и выборка
Всего комбинаций = произведение размеров групп; может быть очень много.
Опции: ограничить длину, выбрать случайную выборку (random.sample по итератору), сортировать по релевантности (к целевой теме).
Автоматическая перефразировка/оценка качества
Можно прогонять сгенерированные варианты через модель оценки качества (например, BERT для классификации релевантности) или через модель перефразирования для улучшения читабельности.
Также фильтры: убрать дубликаты, слишком короткие/длинные фразы, фразы с запрещёнными словами.
Рекомендации по началу
Если нужны простые перестановки и замены — начните с ручного файла groups (строки.txt) и простого itertools.product.
Если нужно «по смыслу» выделять группы из длинного исходного текста — используйте spaCy для POS/NER и sentence-transformers для кластеризации.
Для русского языка полезны: pymorphy2 (морфология), natasha или deeppavlov (NER/разметка), sentence-transformers (универсальные эмбеддинги).
Если хотите, могу:
показать конкретный пример на ваших реальных двух-трёх строках из файла (присылайте 3–5 строк), или
предложить скрипт, который автоматически извлекает группы по POS/NER (для русского) и затем генерирует комбинации, или
показать, как согласовать слова по падежу/числу с pymorphy2.
Скажите, какой вариант интересует — простой шаблонный генератор, автоматическое извлечение тематических групп из текста или продвинутая семантическая кластеризация/перефразировка.
теперь соедени все эти куски кода в один код нашей программы
которая из групп слов в файле txt делает новый текст
немного изменяя комбинации сочетаний групп слов нашего исходного текста
Ниже — единый рабочий Python;скрипт, который читает группы слов из TXT (каждая группа — строка; пустая строка или строка с "#" разделяет блоки), генерирует комбинации (произведение групп), случайно изменяет часть сочетаний и пытается привести прилагательные к форме, согласованной с существительными (используя pymorphy2). Параметры: сколько вариантов сгенерировать, максимальная длина фразы, доля случайных изменений.
Установите зависимости:
pip install pymorphy2
Код (сохраняйте в файл generate_combinations.py):
Python
Копировать код
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Генератор текстов из групп слов.
Формат входного файла:
- Каждая строка — один элемент группы.
- Пустая строка или строка, начинающаяся с '#' отделяет группы.
Пример:
красный
синий
дом
машина
книга
быстро
медленно
"""
import itertools
import random
import argparse
from typing import List
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
def read_groups_from_file(path: str) -> List[List[str]]:
groups = []
current = []
with open(path, 'r', encoding='utf-8') as f:
for raw in f:
line = raw.strip()
if not line or line.startswith('#'): # разделитель групп
if current:
groups.append(current)
current = []
else:
current.append(line)
if current:
groups.append(current)
return groups
def try_agree_pair(left: str, right: str) -> (str, str):
"""
Попытка согласовать первое слово (например, прилагательное) с формой существительного.
Если не удаётся — возвращаем исходные.
Работает только для двухсловных сочетаний; для прочих случаев можно расширить логику.
"""
p_left = morph.parse(left)[0]
p_right = morph.parse(right)[0]
# Если левое — прилагательное (ADJF) или причастие (PRTF), а правое — существительное (NOUN)
if ('ADJF' in p_left.tag or 'PRTF' in p_left.tag) and ('NOUN' in p_right.tag or 'NPRO' in p_right.tag):
# Возьмём граммемы существительного: падеж, число, род
# Если существительное имеет неоднозначные теги, попытаемся взять наиболее вероятную форму
target_case = None
target_number = None
target_gender = None
# Получим доступные граммемы из разбора существительного
tag = p_right.tag
for g in ('nomn','gent','datv','accs','ablt','loct','gen2','acc2'):
if g in tag:
target_case = g
break
# pymorphy2 uses 'sing'/'plur' and 'masc'/'femn'/'neut'
if 'sing' in tag:
target_number = 'sing'
elif 'plur' in tag:
target_number = 'plur'
if 'masc' in tag:
target_gender = 'masc'
elif 'femn' in tag:
target_gender = 'femn'
elif 'neut' in tag:
target_gender = 'neut'
# Сформировать набор граммем для инфлексии прилагательного
gramms = set()
if target_case:
# pymorphy2 internal case tags are like 'nomn' etc., inflect expects these
gramms.add(target_case)
if target_number:
gramms.add(target_number)
if target_gender:
gramms.add(target_gender)
if gramms:
inflected = p_left.inflect(gramms)
if inflected:
return inflected.word, right
return left, right
def try_agree_sequence(words: List[str]) -> List[str]:
"""
Проходим по последовательности слов и пытаемся согласовать пары (adj + noun).
Можно расширить для согласования по падежам и т.д.
"""
out = words[:]
for i in range(len(words)-1):
a, b = out[i], out[i+1]
new_a, new_b = try_agree_pair(a, b)
out[i], out[i+1] = new_a, new_b
return out
def generate_combinations(groups: List[List[str]],
max_results: int = 100,
max_length: int = 100,
randomness_ratio: float = 0.2,
unique: bool = True) -> List[str]:
"""
Генерирует комбинации из групп.
randomness_ratio: доля комбинаций, которые будут случайно модифицированы (перестановка внутри комбинации или
выбор случайного синонима из той же группы).
"""
# Посчитаем общее количество комбинаций (может быть очень большим)
total = 1
for g in groups:
total *= max(1, len(g))
if total > 10**7:
# предотвращаем бесконечную арифметику
break
# Если слишком большой набор, будем сэмплировать
use_all = (total <= max_results * 10) # если не слишком много, возьмём все и затем выберем
results = set() if unique else []
iterator = itertools.product(*groups)
if use_all:
pool = list(iterator)
random.shuffle(pool)
else:
# В случае огромного пространства — не строим весь список, а делаем случайную выборку
# для этого будем генерировать случайные комбинации, выбирая случайные элементы из каждой группы
pool = []
attempts = 0
while len(pool) < max_results * 10 and attempts < max_results * 50:
comb = tuple(random.choice(g) for g in groups)
pool.append(comb)
attempts += 1
for comb in pool:
if len(results) >= max_results:
break
phrase_words = list(comb)
# Применяем автоматическое согласование словой пары
phrase_words = try_agree_sequence(phrase_words)
# Немного "изменяем" часть вариантов по randomness_ratio:
if random.random() < randomness_ratio:
# сделаем небольшую перестановку или замену в рамках одной из групп
i = random.randrange(len(groups))
# выбрать случайный элемент из той же группы, отличающийся от текущего
options = [w for w in groups[i] if w != comb[i]]
if options:
phrase_words[i] = random.choice(options)
else:
# как вариант — поменяем местами две соседние позиции (если есть)
if len(phrase_words) > 1:
j = random.randrange(len(phrase_words))
k = (j+1) % len(phrase_words)
phrase_words[j], phrase_words[k] = phrase_words[k], phrase_words[j]
# пробуем согласовать заново
phrase_words = try_agree_sequence(phrase_words)
# Собирем строку, убираем лишние пробелы
phrase = " ".join(phrase_words).strip()
if len(phrase) == 0 or len(phrase) > max_length:
continue
if unique:
results.add(phrase)
else:
results.append(phrase)
# Вернём список (можно отсортировать)
out_list = list(results) if unique else results
random.shuffle(out_list)
return out_list[:max_results]
def main():
parser = argparse.ArgumentParser(description='Генератор текстов из групп слов (TXT).')
parser.add_argument('input', help='Входной файл с группами слов (txt)')
parser.add_argument('-o', '--output', help='Файл для записи результатов (txt). Если не задан — печать в stdout.')
parser.add_argument('-n', '--num', type=int, default=100, help='Сколько вариантов сгенерировать (по умолчанию 100).')
parser.add_argument('--maxlen', type=int, default=200, help='Максимальная длина фразы (символов).')
parser.add_argument('--rand', type=float, default=0.2, help='Доля случайных изменений (0..1).')
parser.add_argument('--unique', action='store_true', help='Требовать уникальность результатов.')
args = parser.parse_args()
groups = read_groups_from_file(args.input)
if not groups:
print("Не найдено групп в файле.")
return
results = generate_combinations(groups,
max_results=args.num,
max_length=args.maxlen,
randomness_ratio=args.rand,
unique=args.unique)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
for r in results:
f.write(r + "\n")
print(f"Записано {len(results)} строк в {args.output}")
else:
for r in results:
print(r)
if __name__ == '__main__':
main()
Короткие пояснения и советы:
Формат входного файла: каждое слово/фраза в своей строке; пустая строка (или строка с #) разделяет группы. Пример выше.
Скрипт пытается согласовать прилагательное с существительным в соседней позиции; логика простая и не покрывает все случаи и падежи, но для типичных сочетаний поможет.
Если пространство комбинаций очень большое, скрипт делает случайную выборку, чтобы не генерировать миллионы вариантов.
Можно расширить: использовать NLP (spaCy, sentence-transformers) для кластеризации, NER, согласования падежей по контексту, или более сложные правила согласования из pymorphy2.
Если хотите, могу:
адаптировать формат файла (например, разделитель групп через запятую в одной строке),
добавить согласование не только для пар, но и для тройных сочетаний,
показать пример входного файла и несколько сгенерированных вариантов на ваших словах —
тогда пришлите такой пример текста
вот немного другая версия этого кода >
import argparse
import random
import sys
def read_groups(filename):
groups = []
current = []
with open(filename, 'r', encoding='utf-8') as f:
for line in f:
s = line.strip()
if s == '' or s.startswith('#'):
if current:
groups.append(current)
current = []
else:
current.append(s)
if current:
groups.append(current)
return groups
def try_agree_adj_noun(words):
return words
def generate_combinations(groups, max_results=100, max_length=5, randomness_ratio=0.0, unique=False):
all_combinations = []
if not groups:
return all_combinations
indices = list(range(len(groups)))
def build(prefix, i):
if len(prefix) >= max_length or i >= len(groups):
all_combinations.append(prefix[:])
return
for w in groups[i]:
prefix.append(w)
build(prefix, i+1)
prefix.pop()
build([], 0)
if randomness_ratio > 0 and len(all_combinations) > max_results:
take = max_results
sample_size = min(len(all_combinations), max_results)
sampled = random.sample(all_combinations, sample_size)
all_combinations = sampled
if max_results and len(all_combinations) > max_results:
all_combinations = all_combinations[:max_results]
results = []
seen = set()
for combo in all_combinations:
words = try_agree_adj_noun(combo)
line = ' '.join(words)
if unique:
if line in seen:
continue
seen.add(line)
results.append(line)
return results
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--input', '-i', default='input.txt', help='имя файла с группами слов')
parser.add_argument('--output', '-o', help='файл для записи результата')
parser.add_argument('--num', '-n', type=int, default=100, help='макс. количество строк')
parser.add_argument('--maxlen', type=int, default=5, help='макс. длина сочетания')
parser.add_argument('--rand', type=float, default=0.0, help='доля случайности 0..1')
parser.add_argument('--unique', action='store_true', help='только уникальные строки')
args = parser.parse_args()
Python
Копировать код
try:
groups = read_groups(args.input)
except Exception as e:
print(f'Ошибка при чтении файла: {e}', file=sys.stderr)
sys.exit(1)
if not groups:
print("Не найдено групп в файле.")
return
results = generate_combinations(groups,
max_results=args.num,
max_length=args.maxlen,
randomness_ratio=args.rand,
unique=args.unique)
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
for r in results:
f.write(r + "\n")
print(f"Записано {len(results)} строк в {args.output}")
else:
for r in results:
print(r)
if name == 'main':
main()
Свидетельство о публикации №125122706221