为什么在此递归代码中达到“达到最大深度递归”?

时间:2019-01-27 23:33:06

标签: python tail-recursion

我对编码和东西很陌生。我试图在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 :(得分:1)

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

这也避免了函数调用的开销。

答案 1 :(得分:0)

我假设您的问题不是关于检查代码的问题,而是关于如何在标准函数中更改递归函数的问题。尾部递归通常易于管理,因为以某种方式,您不需要存储递归过程中计算出的所有结果,而只需要累加它们即可。 就您而言,这甚至更简单,因为您无需累加结果。

您可以通过以下方式更改代码:

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