For an assignment we were asked to define a fibonacci function, which I accomplished with this:
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
However, I have seen recursive functions, such as the factorial function, defined in a one line return statement like so:
def factorial(n):
return n > 1 and n * factorial(n-1) or 1
So, I attempted to apply the same to my fibonacci function. After several attempts, I got it to work for all tested cases except when s = 0, in which case it returns False when it should return 0. Here is where I am:
def fibonacci(n):
return ((n == 0 or n == 1) and n) or (n > 1 and (fibonacci(n-1) + fibonacci(n-2)))
I understand that python evaluates 0 to False, so how would I have python return zero instead of False when n is 0 while maintaining the current length/structure of the code? Is that even possible?
Also, is this style of creating a function (recursive or otherwise) more or less desirable/pythonic than the textbook version? (I would imagine not just because of readability)
To be clear, I have satisfied the requirements for the assignment, and for personal knowledge only, I would like a clearer understanding of what is happening in the return statement.
The x and y or z
idiom doesn't work if y
is falsy. You can swap the condition to make it work nonetheless:
def fibonacci(n):
return n >= 2 and fibonacci(n-1) + fibonacci(n-2) or n
However, as of Python 2.5 (released 6 years ago), we have proper conditional expressions and don't need the and/or
hack any longer:
def fibonacci(n):
return n if n < 2 else fibonacci(n-1) + fibonacci(n-2)
Now this has an exponential runtime complexity. If you want to be efficient, use the O(n)
algorithm:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
Or even write a generator to yield all the numbers and only take as much as you need.
Perhaps this makes it clearer:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With