【问题标题】:Python: Fibonacci SequencePython:斐波那契数列
【发布时间】:2013-02-24 16:02:34
【问题描述】:

我只是想通过制作一些基本功能来提高我的编程技能。

我想用斐波那契值填充一个列表,但我认为我的代码给出了所有数字的总和并打印出来..

numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

print numberlist

fibonaccinumbers = []

for n in numberlist:
    def fib(n):
        a, b = 0, 1
        for i in range(n):
            a, b = b, a + b
        return a
    a = fib(n)
    fibonaccinumbers.append(a)


print a

我哪里出错了?

【问题讨论】:

  • +1 任何以“我一直在努力提高自己的技能”开头的问题都值得点赞并立即关注
  • 但这是真的,我写这篇文章只是为了更能胜任编程..
  • @georgesl: a, b = b, a + b 在 Python 中非常好。
  • @georgesl,一旦你习惯了它,你会想知道为什么其他语言不能处理像多个返回值这样干净的东西
  • @DaBx 我是完全诚实的!提高是程序员的最高目标

标签: python fibonacci


【解决方案1】:
print a

好吧,你打印最终值。


您的代码中还有一些 cmets:

numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

您不需要在那里初始化i,for 循环会为您完成。此外,您可以通过这样做来简化整个块:

numberlist = list(range(20))

鉴于您实际上并不需要将其作为列表,因此您根本不需要构建它,但您可以稍后运行 for n in range(20)

然后你在循环中一遍又一遍地重新定义你的fib 函数。您应该在它之外定义它并重复使用它。

此外,当您知道要创建一个包含多个斐波那契数字的列表时,只需存储您计算的所有数字会有所帮助。这样你就不必一遍又一遍地做同样的事情。您还可以使用生成器函数来简化这一切:

def fibGenerator():
    a, b = 0, 1
    yield 0
    while True:
        a, b = b, a + b
        yield a

fibonaccinumbers = []
fib = fibGenerator()
for n in range(20):
    fibonaccinumbers.append(next(fib))

您也可以只使用 itertools 中的 take-recipe 来执行此操作,而不是在一个范围内迭代并手动调用生成器上的 next

fibonaccinumbers = take(20, fibGenerator())

关于发电机

但仍然不太确定生成器的作用。

生成器是一个 Python 函数,它生成一系列返回值。这些值是延迟生成的,这意味着当您请求它时。您只需使用yield 而不是return 即可创建生成器。 yield 将“返回”一个值并暂停生成器。下次你请求一个值时,生成器会从它停止的地方继续。

使用生成器可以创建无限序列。正如你在上面fibGenerator 的定义中看到的,有一个无限循环,里面有一个yield。当生成器停止时,尽管有这个循环,它也不会挂断。

这是一个简单的自解释示例:

>>> def example():
    print('begin')
    i = 0
    while True:
        print('Calculating next value')
        yield i
        i += 1

>>> g = example()
>>> next(g)
begin
Calculating next value
0
>>> next(g)
Calculating next value
1
>>> next(g)
Calculating next value
2
>>> next(g)
Calculating next value
3
>>> next(g)
Calculating next value
4

next 函数是从 iterable 请求下一个值的内置函数。可迭代是您可以迭代的任何东西(例如for x in iterable: ...);并且任何生成器也是可迭代的。

【讨论】:

  • @uʍopǝpısdn 哈,第一! :P ^^
  • 我见过的收益声明的最佳解释。它正好适合我对斐波那契数的实验。谢谢!
【解决方案2】:

对不起,我是个白痴。我正在打印“a”,这是斐波那契的最后一次迭代计算..

我应该打印我的清单。

该死的……

【讨论】:

  • 你发的帖子还是不错的。建议:1)将您的函数定义拉到循环之外。 2) Range 返回一个列表,因此您可以只说 for n in range(20) 而不是 for n in numberlist 并在开始时完成所有这些工作。 3)我建议查看列表推导,第二个循环可能类似于:fibonaccinumbers = [fib(n) for n in range(20)]
【解决方案3】:

问题在最后一行。我敢肯定,这会分散注意力:您应该打印列表,而不是 a

其他一些提示:

1:这整个块只是重新创建range返回的列表:

numberlist = []
i = 0
for i in range(20):
    numberlist.append(i)

分配i = 0 也没有实际意义。相反,请尝试:

numberlist = range(20)

在 python 3 中,调用 list(range(20)),因为 range 不会创建完整的列表。

2:在循环的每次循环中重新定义fib 函数不会产生问题,但肯定没有必要。将定义移到外面:)

【讨论】:

  • 哎呀对不起大家,刚刚看到最后的cmets!我会马上解决的。
【解决方案4】:

本着提高编程技能的精神:您可以使用a generatoritertools.islice() 获取第一个n 斐波那契数列:

from itertools import islice

def fib(a=0, b=1):
    yield a
    while True:
        yield b
        a, b = b, a + b

fibonacci_numbers = list(islice(fib(), 20))
print(fibonacci_numbers)

输出

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181]

【讨论】:

    【解决方案5】:

    我想我会分享一些 pyLove:

    def fib(n, a = 0, b = 1):
        seq = [a,b]
        while len(seq) < n:
            seq += [seq[len(seq)-1] + seq[len(seq)-2]]
        return seq
    
    print(fib(13))
    

    输出为:

    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
    

    或:

    #or if you want to make up your own
    print(fib(13, 1597, 2584))
    

    输出为:

    [1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229]
    

    【讨论】:

      【解决方案6】:

      我将其浓缩并接受了“范围”或至少 list(range()) 创建自己的列表的事实:

      numberlist = list(range(20))
      
      def fib(n):
          a, b = 0, 1
          for i in range(n):
              a, b = b, a + b
          return a
      
      fibonaccinumbers = [fib(n) for n in numberlist]
      
      print fibonaccinumbers
      

      它似乎可以打印每个斐波那契值,直到第 20 次迭代。为什么我可以在 def 之外调用 'fib(n)' 而不会做一些奇怪的事情,例如:

      a = fib(n)
      

      这是我以前习惯的风格。不管怎样,现在的程序好看吗?

      【讨论】:

      • 如果你把它改成@J.F. Sebastian 建议,它会运行得更快。 (因为它只在fib 中循环运行一次。)
      • 知道了,我看看能不能做到。
      • 您可能想查看所有答案……另外,请不要仅仅为了添加更多问题而回答您自己的问题,而是编辑您的问题。另请参阅the FAQ
      • 好的,抱歉,感谢您的所有帮助。但是,仍然不太确定生成器的作用。我阅读了提示 (stackoverflow.com/questions/102535/…)
      【解决方案7】:

      斐波那契数列的第n项是:

      在哪里 和

      使用上面的标识,可以使用列表推导生成系列:

      [int(((((1 + math.sqrt(5)) / 2) ** x) - (((1 - math.sqrt(5)) / 2) ** (x))) / math.sqrt(5)) for x in range(n)] //where n is the number of terms in the series
      

      【讨论】:

        【解决方案8】:

        由于每个斐波那契数都是从所有先前的数中生成的,因此从头开始计算每个数是没有意义的。最好使用您收集斐波那契数的列表来计算每个后续数:

        def FibList(n):
            rc = []
            for i in xrange(n):
                if i < 2:
                    rc.append(1)
                else:
                    rc.append(rc[i-2] + rc[i-1])
        
            return rc
        
        print FibList(20)
        

        如果你真的想变得漂亮,你可以创建一个计算斐波那契值的生成器函数,并使用它来构建你的列表:

        def Fib(n):
            n1 = 1
            n2 = 1
        
            for i in xrange(n):
                if i < 2:
                    yield 1
                else:
                    n3 = n1 + n2
                    n1 = n2
                    n2 = n3
                    yield n3
        
        fiblist = [x for x in Fib(20)]
        print fiblist
        

        在生成器函数中,'yield' 关键字返回列表的每个值。 fiblist 使用“列表理解”来使用生成器构建列表的行。您也可以在 for 循环中使用生成器:

        for fnum in Fib(20):
            print fnum
        

        【讨论】:

          【解决方案9】:

          我只是使用了公式并插入了值:

          import math 
          
          def Fibs(n):
          
           for i in range (n):
          
               Fn=int(((((1+math.sqrt(5))**i) - ((1-math.sqrt(5)) **i))/(2**i) * (math.sqrt(5)))/5)
               print (Fn)
          
          Fibs(int(input())
          

          【讨论】:

            【解决方案10】:
            def fibonacci(number):
                    numbers = [0, 1]
                    while len(numbers) < number:
                        numbers[len(numbers):len(numbers)] = [numbers[len(numbers)-2] + numbers[len(numbers)-1]]
                    return numbers
            

            每次循环运行时,列表中的最后两个值都会相加。 在迭代到输入长度时,使用每个新的斐波那契值在列表中创建一个新位置。

            【讨论】:

              【解决方案11】:

              为什么不使用列表推导?这是我解决问题的方法。我将定义一个函数来计算斐波那契数列的 n 项,如下所示。

              def fibo(n):
                  if n<=2:
                      return 1
                  else:
                      res = fibo(n-1) + fibo(n-2)
                  return res
              

              然后我会使用列表推导来获得我想要的序列。

              fib_sequence = [fibo(i) for i in range(n+1)]
              

              【讨论】:

                猜你喜欢
                • 2013-08-03
                • 2014-05-23
                • 2015-06-05
                • 2022-01-14
                • 1970-01-01
                • 1970-01-01
                • 2014-05-19
                相关资源
                最近更新 更多