Python 递归 Try-Except

Python Recursive Try-Except

我正在尝试创建一个递归 try-except 函数来处理偶尔出现的错误。在 pandas 中,我们可以为数据帧创建分位数,但是,两个或多个分位数的边界可能会重合,因此实际上没有边界。所以pandas会抛出一个错误。要避免这种情况,您只需降低分位数的数量,这就是我在这里尝试做的。

import pandas as pd

quantiled, dict_bins = recursive_lower_labels(model_quant = model_quant,
                                              n_quantiles = n_quantiles,
                                              reverse = reverse)
def recursive_lower_labels(model_quant,
                           n_quantiles,
                           reverse = False):
    '''
    Recursively lowers the number of labels until it works.
    '''

    if n_quantiles == 0: # base case
        return 'Error: There are no Quantiles to be used.'

    # Not very important... 
    # I'm using this to either use normal or reverse labels.
    if reverse == False:
        labels = range(1, n_quantiles + 1)
    elif reverse == True:
        labels = range(n_quantiles, 0, -1)

    try:

        qt, dc = pd.qcut(model_quant, 
                         q = n_quantiles,
                         labels = labels,
                         retbins = True)

        return qt, dc

    except:

        recursive_lower_labels(model_quant,
                               n_quantiles = n_quantiles - 1,
                               reverse = reverse)

我得到的错误是(指向顶部的函数调用):

cannot unpack non-iterable NoneType object

我怀疑这是我犯的两个错误之一:

  1. 某处的范围界定存在问题。也许 n_quantiles?从我没有经验的调试来看,这似乎不太可能。
  2. except 语句内的函数递归调用之前放置 return 存在问题。我在这里尝试了很多组合,即使最后有一个额外的 else 也没有用。

顺便说一句,如果不是递归的,这确实有效。

编辑:

我的问题被标记为重复,此编辑是为了解决该评估。首先,它被标记为一个问题的副本,该问题也被标记为这样,这很奇怪,但并不相关。将这些问题与我的问题区分开来的重要且有用的概念是,它们都有函数,尽管递归,但不一定总是 return 某些东西,而我的总是 return 某些东西,因此,使递归中的 return 似乎是不必要的——事实证明 not 是真的。

您所要做的就是return您的递归。通过一些轻度重构:

def recursive_lower_labels(model_quant,
                           n_quantiles,
                           reverse=False):
    """
     Recursively lowers the number of labels until it works.
    """
    if n_quantiles == 0:  # base case
        return 'Error: There are no Quantiles to be used.'

    # Not very important...
    # I'm using this to either use normal or reverse labels.
    if reverse:
        labels = range(n_quantiles, 0, -1)
    else:
        labels = range(1, n_quantiles + 1)

    try:
        return pd.qcut(model_quant,
                         q=n_quantiles,
                         labels=labels,
                         retbins=True)

    except:
        return recursive_lower_labels(model_quant,
                                      n_quantiles=n_quantiles - 1,
                                      reverse=reverse)