Как преждевременно выйти из рекурсивной функции декартового произведения после того, как решение найдено? - PullRequest
1 голос
/ 26 мая 2020

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

В настоящее время я использую продукт itertools () внутри понимания списка, т.е. брут-форс, каждая перестановка проверяется перед возвратом значения. Вот соответствующая часть в Python 3:

from itertools import product


def cartesian_match(string, iterables):
    """Gets the phonetic spelling breakdown of a word via cartesian product.

    Args:
        string (str):     String for which a matched spelling is wanted.
        iterables (list): A list of lists of unknown number and length.
                          Each sublist contains only str elements.
                          Each sublist contains all possible spellings of a
                          phoneme.

    Returns:
        list: the first matched list of spelling units.

    Example (simplified):
      Args:
        string = "python"
        iterables = [
          'p', 'pp'],['i', 'ie', 'y', 'igh'],['th'],['or', 'ou', 'e', 'o'],[
          'nd', 'nn', 'n', 'ne']

      Returns:
        ['p', 'y', 'th', 'o', 'n']

    """
    return [x for x in product(*iterables) if "".join(x) == string][0]

Для сложных слов декартово произведение велико, десятки миллионов перестановок. Для вычисления некоторых слов требуется более 15 минут. У меня есть тысячи слов для анализа, поэтому скорость в настоящее время является проблемой.

Чтобы ускорить процесс, мне нужна функция, которая возвращает значение, как только оно обнаруживается, вместо того, чтобы формировать декартово произведение и запускать через каждую перестановку. Это также позволило бы мне оптимизировать последовательность элементов внутри каждого подсписка, чтобы быстрее получить соответствующее значение.

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

Может ли кто-нибудь указать мне правильное направление?

1 Ответ

1 голос
/ 26 мая 2020
for x in in product(*iterables):
    if "".join(x) == string:
        return x

BTW: ваша функция не рекурсивна - название этого вопроса вводит в заблуждение.

...