【问题标题】:Continuous TypeError when attempting to add integers in a list?尝试在列表中添加整数时出现连续类型错误?
【发布时间】:2021-03-11 09:37:19
【问题描述】:

好的。在这个问题上遇到这么多麻烦,我觉得有点傻,但基本上,这是我到目前为止的代码:

def addition_nest(x):
    netsum = 0
    sublist = []
    if isinstance(x, int):
        return x
    if isinstance(x, list):
        for sublist in x:
            if sublist == []:
                return netsum
            else:
                netsum = netsum + addition_nest(sublist)
        return netsum

我不断收到错误消息,说操作数 + 不适用于 int 和 NoneTypes。关于如何绕过这个的任何想法?代码基本上需要能够将列表/嵌套列表中的所有整数相加,并省略列表中的任何其他元素。

【问题讨论】:

  • 如果您缩进 netsum = 0 行,您的代码似乎可以正常工作。什么样的输入会给你带来这个问题?
  • 如果没有实际运行代码,我很确定错误来自以下行:netsum = netsum + addition_nest(..)(尝试添加整数(netsum)和可能的 NoneType(递归调用的返回值)。现在要弄清楚你的函数在哪里可能返回一个无,你应该追踪所有返回点。在你的代码中,最后一行是隐式的return None。所以,你是否传递了任何既不是 int 也不是列表的嵌套元素? 如果是这样,最后一行应该只是说:return 0
  • 您是否考虑过如果x 既不是int 也不是list 会发生什么?

标签: python recursion iteration


【解决方案1】:

此代码将为您提供预期的输出。

def addition_nest(x):
    netsum = 0
    if isinstance(x, int):
    # if isinstance(x, (int, float)):
        return x
    elif isinstance(x, list):
        for each_element in x:
            if isinstance(each_element, int):
            # if isinstance(each_element, (int, float)):
                netsum += each_element
            elif isinstance(each_element, list):
                netsum += addition_nest(each_element)
        return netsum

print(addition_nest(25))  ## Output: 25
print(addition_nest([25, 30, 'a']))  ## Output: 55
print(addition_nest([25, 30, ['a', 10, 20]]))  ## Output: 85

如果您还希望上述代码与 float 一起使用,请将 if 条件替换为注释行。

在您现有的代码中,您已经处理了当父列表中的元素是另一个列表或整数时的场景。但是您没有为其他数据类型处理它。这就是您面临错误的原因。

【讨论】:

  • 为什么奇怪地使用replace()isdigit() 而不是简单的isinstance(x, (int, float))
  • 你还需要替​​换其他类型测试,if isinstance(x, int):,否则addition_nest(25.4)不起作用。
  • 这段代码使用addition_nest('a')而不是显式返回一个隐式。两个显式返回和一个隐式返回似乎不是好的代码风格。
  • 我的代码还有另一个问题:如果您可视化递归树,检查isinstance(x, int)(或list)的步骤发生在两者深度 L 和 L+1。他们总是可以统一的。这是一个简化版:ideone.com/XWuQ28
【解决方案2】:

首先,第三行没用,没有意义

sublist = []

其次,如果它是一个列表,只需简单地调用每个元素上的函数并相加即可。

def addition_nest(x):
    netsum = 0
    sublist = []
    if isinstance(x, int):
        return x
    if isinstance(x, list):
        for sublist in x:
            netsum = netsum + addition_nest(sublist)
        return netsum

这样就可以了。

【讨论】:

    【解决方案3】:

    我认为这个问题比你和其他答案更简单。递归的第一条规则是让递归完成工作:

    def addition_nest(unknown):
        if isinstance(unknown, list):
            if unknown:  # not empty
                head, *tail = unknown
                return addition_nest(head) + addition_nest(tail)
    
            return 0  # empty
    
        if isinstance(unknown, (int, float)):
            return unknown
    
        return 0  # neither list nor number
    

    OTOH,如果我们想减少递归并提高效率,我们可以朝以下方向发展:

    def addition_nest(unknown):
        if isinstance(unknown, (int, float)):
            return unknown
    
        if isinstance(unknown, list):
            return sum(map(addition_nest, unknown))
    
        return 0
    

    这仍然是 递归,虽然 间接 因为我们不直接从自身调用函数,而是将其交给@987654324 @。

    【讨论】:

    • -1:IMO 避免循环可能不是一个好建议。我不会将简单的迭代(例如对列表)变成不必要的递归——它牺牲了可读性、简单性和可能的​​性能,而几乎没有任何回报。
    • @UltraInstinct,我已经删除了令人反感的第二条规则,并在我的编辑评论中指出它本质上是固执己见的,正如你对它的反对一样。我认为这是一个递归练习,那么为什么不只使用递归来解决它呢?我个人认为它与其他混合递归和迭代但有缺陷的答案一样可读:混合隐式和显式返回;未使用的变量。希望我能满足您的反对意见!
    • 反转了 -1 :)。至于其他答案,我也不同意其中任何一个。这是我的答案版本(希望 OP 看到它):ideone.com/XWuQ28
    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 2015-10-22
    • 2013-10-18
    • 1970-01-01
    • 2011-11-21
    • 2016-12-30
    • 2019-11-20
    • 2021-05-29
    相关资源
    最近更新 更多