创建一个删除整数奇数位的递归函数

Creating a recursive function that removes odd digits of an integer

我刚开始使用递归函数,我必须创建一个接收整数和 return 仅包含偶数位的新数字的函数。例如,如果它收到 23456,它应该 return 246。这是我试过的:

def newInt(n):
    dig = n % 10
    if dig % 2 == 1:
        return newInt(n//10)
    elif dig % 2 == 0:
        return str(n) + newInt(n//10)

print(newInt(32))

但我收到以下错误:

RecursionError: maximum recursion depth exceeded in __instancecheck__

关于我应该如何修复它的任何提示?

您需要一个基本案例。也不需要将任何整数转换为字符串。这是解决这两个问题的 newInt() 的工作版本:

def newInt(n):
    if not n:
        return 0
    dig = n % 10
    if dig % 2 == 1:
        return newInt(n // 10)
    else:
        return 10 * newInt(n // 10) + dig

您的问题是您没有条件停止递归 - 每次调用 newInt 都会导致另一个调用。停止的一种方法是检查 n 是否小于 10,然后检查 return n 是否为偶数。例如:

def newInt(n):
    if n < 10:
        return n if n % 2 == 0 else 0
    dig = n % 10
    if dig % 2 == 1:
        return newInt(n//10)
    elif dig % 2 == 0:
        return newInt(n//10) * 10 + dig

请注意,我已将您的函数修改为 return 整数而不是字符串。

这是 divmod 的变体。取消注释打印以查看其工作原理:

def newInt(n):
    d,r = divmod(n,10)
    # print(n,d,r)
    if d == 0:
        return 0 if r%2 else r
    if r % 2:
        return newInt(d)
    else:
        return 10*newInt(d)+r
    
print(newInt(212033450))

输出:22040

这是使用 Python 3.10 match..case 语法重写的@mozway 算法 -

def newInt(n):
  match divmod(n, 10):
    case (0, r) if r & 1:
      return 0
    case (0, r):
      return r
    case (d, r) if r & 1:
      return newInt(d)
    case (d, r):
      return 10 * newInt(d) + r
print(newInt(67120593306737201))
6200620

注意 r & 1 对于测试数字是偶数还是奇数更有效。 r % 2 执行除法,而 & 只检查第一位。

您甚至不需要为每个循环突破挖掘:

def newInt(n):
    if n:
        if n & 1:
            return newInt(n // 10)
        else:
            return 10 * newInt(n // 10) + (n % 10)
    return 0