【问题标题】:python syntax: how to return 0 instead of False when evaluating 0python语法:评估0时如何返回0而不是False
【发布时间】:2012-05-18 08:51:36
【问题描述】:

对于一个任务,我们被要求定义一个斐波那契函数,我用这个来完成:

def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

但是,我看到递归函数,例如阶乘函数,在单行返回语句中定义,如下所示:

def factorial(n):
    return n > 1 and n * factorial(n-1) or 1

因此,我尝试将其应用于我的斐波那契函数。经过几次尝试,我让它适用于所有测试用例,但 s = 0 时除外,在这种情况下,它应该返回 0 时返回 False。这就是我所在的位置:

def fibonacci(n):
    return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))

我知道 python 将 0 评估为 False,那么当 n 为 0 时,我如何让 python 返回零而不是 False,同时保持代码的当前长度/结构?这可能吗?

此外,这种创建函数(递归或其他方式)的风格是否比教科书版本更可取/更不理想? (我想不仅仅是因为可读性)

明确地说,我已经满足了作业的要求,并且仅出于个人知识,我希望更清楚地了解 return 语句中发生的事情。

【问题讨论】:

  • 您需要编写一个递归斐波那契函数,还是仅仅a斐波那契函数?因为递归实现的运行时间非常糟糕(指数),而非递归实现通常是线性的。 pythonic 的东西可能是产生斐波那契数列的生成器......
  • @mata:这个作业旨在说明递归的概念。

标签: python syntax return return-value


【解决方案1】:

如果y 是falsy,则x and y or z 习语不起作用。您仍然可以交换条件以使其正常工作:

def fibonacci(n):
    return n >= 2 and fibonacci(n-1) + fibonacci(n-2) or n

但是,从 Python 2.5(6 年前发布)开始,我们有了正确的 conditional expressions 并且不再需要 and/or hack:

def fibonacci(n):
    return n if n < 2 else fibonacci(n-1) + fibonacci(n-2)

现在这具有指数级的运行时复杂性。如果要高效,请使用O(n) 算法:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

或者甚至编写一个生成器来生成所有数字,并且只取所需的数量。

【讨论】:

  • 请注意,在 Python 2.5 中引入 y if x else z 之前,人们曾经使用过 x and y or z 东西,因为这个成语存在这个问题,而且无论如何它都很难看。
  • 是的,伙计们,我认为现在每个人都会使用 2.5 以上的东西 :) 说清楚了。
  • @jgritty 0 or 0 是 0 因为第二件事是 0。 True and 0 or 'oops' 将评估为 'oops'。
  • @Verbal:不,为了清楚起见,在这种情况下我会使用明确的if: / else:。这些示例只是为了向您展示如何在必要时在一行中完成(并通知您不应使用x and y or z)。
  • @Verbal:是的,请看我的编辑,如果你也对此感兴趣,你可以在性能方面做得更好。
【解决方案2】:

也许这样更清楚:

def fibonacci(n):
    print ((n == 0 or n == 1) and n)
    print (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
    return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))


print 0 or False
print False or 0

【讨论】:

  • print 是我的朋友,我在这方面学到了很多东西,但这个想法让我没有想到。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-09-11
  • 2015-06-21
  • 2019-04-19
  • 2012-01-05
  • 2018-08-16
  • 1970-01-01
  • 2016-08-25
  • 1970-01-01
相关资源
最近更新 更多