@okolo178186

Как проверить полученную случайную выборку в Python по ряду условий?

что не так в этом кусочке кода.
Его задача - сгенерировать случайную последовательность букв, а затем проверить ее по ряду условий. И если эти условия соблюдаются, то сгенерировать заново. И так - пока не будет сгенерирована последовательность, внутри которой не будет недопустимых сочетаний (в данном примере такие недопустимые сочетания - это три гласных или три согласных подряд).

ABC = ['А', 'Б', 'В', 'Г', 'Д', 'E', 'Ё', 'Ж', 'З', 'И', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я'] #все буквы алфавита
A = ['А', 'E', 'Ё', 'И', 'О', 'У', 'Ы', 'Э', 'Ю', 'Я'] #все гласные
B = ['Б', 'В', 'Г', 'Д', 'Ж', 'З', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ'] #все согласные
import random
creature = '' #задаем переменную для итоговой последовательности букв
fish = random.choices(ABC, k = 8) #делаем промежуточную случайную выборку из алфавита длиной 8 символов, которую далее надо будет проверить на предмет недопустимых сочетаний внутри нее
for i in range (len(fish) - 1): #каждую букву промежуточной выборки fish проверяем по следующим условиям
    while fish[i] in B and fish[i-1] in B and fish[i+1] in B or fish[i] in A and fish[i-1] in A and fish[i+1] in A:
        fish = random.choices(ABC, k = 8) #если перечисленные выше условия верны, то есть в промежуточной выборке есть недопустимые сочетания, то выборка производится заново - и так в рамках цикла, пока эти условия не будут False
for letter in fish: #склеиваем выбранные буквы в одно слово
    creature += str(letter)
print(creature)


В общем, похоже, что цикл for и вложенный цикл while - нерабочие. В итоге выводится просто промежуточная выборка fish из 8 символов, которая была задана до начала цикла (то есть условия сочетаний символов внутри выборки, заданные в цикле, никак не соблюдаются).
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 2
Dr_Elvis
@Dr_Elvis Куратор тега Python
В гугле забанен
import random

ABC = ['А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж', 'З', 'И', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ы', 'Ь', 'Э', 'Ю', 'Я']
A = ['А', 'Е', 'Ё', 'И', 'О', 'У', 'Ы', 'Э', 'Ю', 'Я']
B = ['Б', 'В', 'Г', 'Д', 'Ж', 'З', 'К', 'Л', 'М', 'Н', 'П', 'Р', 'С', 'Т', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ']

creature = ''
while True:
    fish = random.choices(ABC, k=8)
    for i in range(2, len(fish)):
        if fish[i] in A and fish[i-1] in A and fish[i-2] in A:
            break
        if fish[i] in B and fish[i-1] in B and fish[i-2] in B:
            break
    else:
        creature = ''.join(fish)
        break

print(creature)

Здесь мы используем бесконечный цикл while True, чтобы генерировать случайные последовательности букв, пока не будет найдена последовательность, которая удовлетворяет условиям.

Для генерации случайных последовательностей мы используем функцию random.choices, которой передаем список ABC и длину последовательности k.

Затем мы проверяем каждый элемент последовательности на предмет наличия недопустимых сочетаний гласных или согласных букв, используя цикл for и оператор if. Если мы находим такие сочетания, мы выходим из цикла с помощью оператора break. Если недопустимых сочетаний нет, мы объединяем выбранные буквы в итоговую строку creature с помощью метода join и выходим из цикла while True с помощью оператора break.

Наконец, мы выводим итоговую строку на экран с помощью функции print.
Ответ написан
Vindicar
@Vindicar
RTFM!
Опиши правила генерации как конечный автомат. Например, так:
rules = {
    # id_состояния: переходы
    # каждый переход - пара (набор_символов, следующее состояние)
    # будет выбран случайный переход, потом случайный символ из его набора символов
    # это начальное состояние. Можно генерировать любые символы.
    'default': [ (A, '1_vowel'), (B, '1_consonant') ], 
    # последний символ был гласной - следующая гласная будет последней
    '1_vowel': [ (A, '2_vowels'), (B, '1_consonant') ],
    # два последних символа были гласными - можем добавлять только согласные
    '2_vowels': [ (B, '1_consonant') ],
    # с согласными по аналогии
    '1_consonant': [ (A, '1_vowel'), (B, '2_consonants') ],
    '2_consonants': [ (A, '1_vowel') ],
}

Очевидно, правила могут быть и более сложными, такая схема это позволяет. Более того, можно описывать допустимые слоги и их сочетания вместо допустимых букв.
А использовать их можно примерно так:
from random import choice

def generate(rules: dict[str, list[tuple[list, str]]], min_length: int) -> str:
    output = ''
    state = 'default'  # начальное состояние
    while len(output) < min_length:
        if not rules[state]:  # если нет переходов
            break  # прерываем цикл, так как уйти из этого состояния нельзя
        transition = choice(rules[state])  # случайно выбираем один из переходов
        output += choice(transition[0])  # случайно выбираем очередной символ согласно переходу
        state = transition[1]  # переходим в следующее состояние
    return output  # возвращаем то, что нагенерировали

Тогда гарантируется, что сгенерированная строка будет соответствовать условиям.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы