Почему в этом рекурсивном коде я получаю "Максимальная рекурсия достигнута"? - PullRequest
0 голосов
/ 28 января 2019

Я очень новичок в кодировании и прочем.Я пытался реализовать приведенный ниже код на python для задачи анализа настроений.Тем не менее, мой документ довольно большой, и когда он пытается зациклить документы с помощью функции, я получаю сообщение об ошибке, указывающее, что достигнута максимальная глубина рекурсии.После прочтения блогов я узнал, что код вызывает себя в операторе return и это вызывает проблему.Следовательно, ищите какое-то руководство или помощь от вас, ребята, из какого-либо псевдокода, чтобы переписать код.Найдите код ниже:

def sentence_score(sentence_tokens, previous_token, acum_score):    
    if not sentence_tokens:
        return acum_score
    else:
        current_token = sentence_tokens[0]
        tags = current_token[2]
        token_score = sum([value_of(tag) for tag in tags])
        if previous_token is not None:
            previous_tags = previous_token[2]
            if 'inc' in previous_tags:
                token_score *= 2.0
            elif 'dec' in previous_tags:
                token_score /= 2.0
            elif 'inv' in previous_tags:
                token_score *= -1.0
        return sentence_score(sentence_tokens[1:], current_token, acum_score + token_score)

Ответы [ 2 ]

0 голосов
/ 28 января 2019

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

Вы можете изменить свой код следующим образом:

def sentence_score(sentence_tokens, previous_token, acum_score):
    while sentence_tokens:
        current_token = sentence_tokens[0]
        tags = current_token[2]
        token_score = sum([value_of(tag) for tag in tags])
        if previous_token is not None:
            previous_tags = previous_token[2]
            if 'inc' in previous_tags:
                token_score *= 2.0
            elif 'dec' in previous_tags:
                token_score /= 2.0
            elif 'inv' in previous_tags:
                token_score *= -1.0
        sentence_tokens = sentence_tokens[1:]
        previous_token = current_token
        acum_score = acum_score + token_score
    return acum_score

Обновить : Приведенный выше код показывает, как преобразовать исходный код в нерекурсивный код.Как подчеркивает @ chris-hunt, этот код (как и оригинальный) может выполнять копию списка каждый раз, когда мы выполняем назначение sentence_tokens[1:].Следовательно, некоторая легкая оптимизация может быть применена к предлагаемому решению для оптимизации кода.В частности, я думаю, что следующее - это лучшее, чего мы можем достичь, не зная подробностей используемых вами структур данных.

def sentence_score(sentence_tokens, previous_token, acum_score):
    for current_token in sentence_tokens:
        tags = current_token[2]
        token_score = sum([value_of(tag) for tag in tags])
        if previous_token is not None:
            previous_tags = previous_token[2]
            if 'inc' in previous_tags:
                token_score *= 2.0
            elif 'dec' in previous_tags:
                token_score /= 2.0
            elif 'inv' in previous_tags:
                token_score *= -1.0

        previous_token = current_token
        acum_score = acum_score + token_score
    return acum_score
0 голосов
/ 28 января 2019

Python не имеет хвостовой рекурсии, просто используйте вместо этого цикл:

def sentence_score(sentence_tokens):
    score = 0
    previous_token = None
    for current_token in sentence_tokens:
        tags = current_token[2]
        token_score = sum([value_of(tag) for tag in tags])
        if previous_token is not None:
            previous_tags = previous_token[2]
            if 'inc' in previous_tags:
                token_score *= 2.0
            elif 'dec' in previous_tags:
                token_score /= 2.0
            elif 'inv' in previous_tags:
                token_score *= -1.0
        score += token_score
        previous_token = current_token
    return score

это также позволяет избежать издержек при вызове функции.

...