使用 while 循环列表理解?

List comprehension using while loop?

有没有办法在列表理解中使用 while 循环。

例如,我有一个单线斐波那契生成器:

[int(((1+(5**0.5))**n-(1-(5**0.5))**n)/(2**n*(5**0.5))) for n in range(100)]

但我希望它在特定结果处停止,而不是仅 运行 特定次数。 (即所有低于 4,000,000 的斐波那契数列)

这是一个关于列表理解的问题,而不是关于一般列表的问题。

更通用的措辞可能是这样的:

[(formula using incrementing variable) 
    for incrementing variable while (result is less than specified amount)]

python 没有在推导中使用 while 的功能(这就像一个 map 结合过滤器),但是你可以使用其他工具来完成它,比如制作一个函数做你想做的或使用你最好的朋友 itertools 模块。例如

示例 1,使用 itertools

>>> from itertools import takewhile
>>> def fib():
        fk,fk1 = 0,1
        while True:
            yield fk
            fk, fk1 = fk1, fk + fk1


>>> list(takewhile(lambda fn:fn<100,fib()))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> 

示例 2,带有函数

>>> def fib_while(tope):
        fk,fk1 = 0,1
        while fk < tope:
            yield fk
            fk,fk1 = fk1, fk + fk1


>>> list(fib_while(100))
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>>    

哦,我忘了说,但是你的斐波那契数列计算公式,即使数学正确,也注定无法获得足够大的 n 的真实值,因为 floating point arithmetic rounding errors

背离点很容易找到(用上面的fib

>>> def fib_float(n):
        return int(((1+(5**0.5))**n-(1-(5**0.5))**n)/(2**n*(5**0.5)))

>>> [n for n,f in zip(range(100),fib()) if f!=fib_float(n)] )
[72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>>

所以对于所有 n>=72 你得到的不是斐波那契数...

如果您只关心序列中低于 4,000,000 的所有数字,那么这当然不是问题,因为限制是 n=33