Как рандомизировать порядок операторов if / elif? - PullRequest
0 голосов
/ 29 августа 2018

Сначала немного предыстории, чтобы вы знали, что я пытаюсь сделать. Я создаю произносимый генератор слов. Чтобы сделать слова произносимыми, только некоторые наборы букв могут следовать за членами другого набора букв. Например, слово не может начинаться с «dtb». Это было достаточно легко реализовать с помощью строки операторов if для добавления буквы, если в слове выполняются условия. Однако, поскольку это генератор случайных слов, я хотел бы рандомизировать порядок, в котором выполняются операторы if / elif. Я подумал, что наилучшим способом было бы иметь список функций (где каждая функция представляет оператор или правило if). ), перемешайте список и выполняйте итерацию до тех пор, пока не будет выполнено условие. Это может быть достигнуто путем явного определения функций, как показано ниже для каждого правила:

string = ''
def rule1():
    string += random_letter
    if string[0] in letter_set_A:
        string += random_from_letter_set_B
    return string

Однако я бы предпочел не делать этого, так как в итоге получилось бы более десятка явных функций, связанных с именами, которые мне не нужны. Я посмотрел дальше на лямбды, чтобы сделать неявные функции в списке, но они не поддерживают назначения, как я использую выше.

Возможно ли создать список сложных функций, подобных приведенным выше, которые можно вызывать в формате my_list[i]() без их явного определения? Если нет, как я могу рандомизировать порядок выполнения операторов if / elif?

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Предположим, у вас есть словарь key:value, в котором в качестве ключа указан символ c, а в качестве значения - список с разрешенными для него символами.
В таком случае вы могли бы сделать что-то вроде

import random

allowed = {'a':['b'],'b':['c'],'c':['a']}

n_chars = 4

word = random.choice(list(allowed.keys()))

while len(word) < n_chars:
    word += random.choice(allowed[word[-1]])

Тот же метод работает в случае более сложных функций, таких как:

import random

def f1(): 
    return "a"
def f2(): 
    return "b"
def f3(): 
    return "c"  

allowed = {'a':[f1,f2],'b':[f2,f3],'c':[f3,f1]}

n_chars = 4

word = random.choice(list(allowed.keys()))

while len(word) < n_chars:
    word += random.choice(allowed[word[-1]])()
0 голосов
/ 29 августа 2018

Да, вы можете к этому. Все в Python является объектом; Вы можете иметь список функций так же легко, как, скажем, список словарей. Это было бы что-то вроде

rule_table = [
    rule1, rule2, rule3,
    ...
]

И тогда вы можете использовать random.choice или другой метод для вызова функции, как вы и предлагали.

Поскольку у вас есть формальный набор правил, вы можете получить лучшую структуру, читая о формальных грамматиках. Существует множество инструментов, позволяющих превратить набор локально-чувствительных правил последовательности в различные приемлемые строки. Возможно, вы также захотите посмотреть цепочки Маркова на предмет вероятностных изменений в состоянии системы.

Этого достаточно, чтобы занять тебя на неделю?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...