3

Possible Duplicate:
Fibonacci numbers, with an one-liner in Python 3?

It may be very easy thing, but I am very new to Python. I came up with this single statement Fibonacci.

[fibs.append(fibs[-2]+fibs[-1]) for i in xrange(1000)]

Not really single statement, though. I need to initialise the list, fibs, before firing this statement i.e. fibs = [0, 1].

Now, I have 2 questions,

  1. How can we get rid of this list initialisation statement, fibs = [0, 1], in order to make it really single statement?

  2. Original statement prints None n times; where n is the number passed in xrange(). Is there any way to avoid that altogether? Or better if the statement can print the series, instead. Then we don't need to print fibs explicitly.

[Edited]

Or do we have any alternative to list.append() which returns the list it appends to?

Community
  • 1
  • 1
Adeel Ansari
  • 39,541
  • 12
  • 93
  • 133

3 Answers3

3

This works:

for n in range(1000):
    print(0.4472135954999579392818347337462552470881236719223051448541*(pow(1.6180339887498948482045868343656381177203091798057628621354,n) - pow(-0.618033988749894848204586834365638117720309179805762862135,n)))

This is an implementation of Binet's Formula. http://en.wikipedia.org/wiki/Fibonacci_number#Relation_to_the_golden_ratio

Zéychin
  • 4,135
  • 2
  • 28
  • 27
  • 1
    It should work for Python's `int` numbers, but it is still precision-dependant and I wouldn't rely on it. Nice thought, though :) – Evpok Jun 28 '11 at 09:47
  • If Python supported(supports?) symbolic Mathematics, this would be solvable exactly for all n >=1 within limitations of the largest available variable size. (I'm not a Python developer, here. :P.) – Zéychin Jun 28 '11 at 09:52
  • I am no pro of floating point, so I'll keep reserve, but I still think that introducing floats in pure integer context is wicked. Didn't deserve the downvote, though. – Evpok Jun 28 '11 at 09:57
  • 1
    Although +1 for the implimentation – Jakob Bowyer Jun 28 '11 at 10:07
  • I could have sworn that I wrote O(log(n)) time, but apparently when it's 6:00 A.M. and you haven't slept, you start replacing log(n) with 1. X_X. It's been a long night in the house. Thanks for correcting me. – Zéychin Jun 28 '11 at 10:08
2

Well, this is not idiomatic at all. What you are doing here is using a list comprehension as a shortcut for a for loop. Though Python's comprehensions can have side effects, Python is not designed for this. I can't think of no way to get this to work and it is probably a good thing.

For your 2), consider that you are actually creating a list which items are return values of the call fibs.append(fibs[-2]+fibs[-1]) which is a side effect method and thus return None. See the doc for details.

Nice try but this is not what Python is for :)

Evpok
  • 4,273
  • 3
  • 34
  • 46
  • Suppose if it were implemented as, where `append()` returns the `list`. Then it would have been possible to do something like this, `list.append().append().append()`. I don't see any problem with this. – Adeel Ansari Jun 28 '11 at 09:56
  • @Adeel Ansari It's just that it is not idiomatic, that's all. Python is as much a coding style as a language. As for why side effects return `None`, see http://stackoverflow.com/questions/4567409/python-image-library-how-to-combine-4-images-into-a-2-x-2-grid/4568169#4568169. To do chained append, consider http://docs.python.org/dev/py3k/library/stdtypes.html#sequence-types-str-bytes-bytearray-list-tuple-range sequence `+` operator. – Evpok Jun 28 '11 at 10:08
  • 1
    Evpok: Thanks, I do agree with the first. For 2nd I came up with a dirty work-around, as dirty as I got 2 negative votes :). Folks doesn't understand that it was just for fun. Anyways, +1 for your inputs. – Adeel Ansari Jun 29 '11 at 02:28
  • Dirty Python code is evil, but fun is excuse enough. Thanks :) – Evpok Jun 29 '11 at 07:14
1
def fib(n):
    return (n in (0,1) and [n] or [fib(n-1) + fib(n-2)])[0]

try this out

Samuele Mattiuzzo
  • 10,760
  • 5
  • 39
  • 63
  • if you want you can also use a lambda expression like this one: lambda n: (n in (0,1) and [n] or [fib(n-1) + fib(n-2)])[0] but you better understand how it works :) – Samuele Mattiuzzo Jun 28 '11 at 09:32
  • 1
    Firstly, its very slow, as you can see. Secondly, I know we can come up with a function/method and then keep calling that as a single statement. That is not what I want. Thirdly, your solution is just giving me the last value, not the complete series. – Adeel Ansari Jun 28 '11 at 09:34
  • 1
    @Adeel: I know its not what you are looking for but speaking performance...you should try this: **return ((1+math.sqrt(5))**n-(1-math.sqrt(5))**n)/(2**n*math.sqrt(5))** – maozet Jun 28 '11 at 09:59
  • 2
    @Adeel, maozet This is known as Binet's Formula and it is what I implemented in another answer. – Zéychin Jun 28 '11 at 10:12