编写依赖于先前值的列表理解?

Writing list comprehensions dependent on previous values?

我以前看过 问题,但它只处理本质上是线性的递归。我正在寻找更通用的东西。

假设我有以下代码

n = 10
num_bits = [0]
for i in range(n):
    nums_bits.append(num_bits[i>>1]+i%2)

此代码将计算 num_bits,一个包含 11 个元素的值数组,其中 num_bits[i] 表示表示 i 所需的位数。

是否可以将其写成列表理解?这样的东西行不通

num_bits = [0]*11
num_bits = [num_bits[i>>1]+i%2 for i in range(11)]

因为理解不会在求值过程中更新 num_bits 的值。除了 for 循环之外,有没有一种规范的方法可以做这样的事情?

P.S。我知道还有其他方法可以解决此问题:我只是将其用作更好地了解 Python 功能的工具。

编辑:总而言之,我想知道生成依赖于先前值的值列表的正确方法是什么。举一个更简单的例子,考虑斐波那契数列

fibonacci = [0,1]
for i in range(10):
    fibonacci.append(fibonacci[-1]+fibonacci[-2])

有没有办法在理解中生成这些数字?如果没有,除了 for 循环(或者 for/while 循环是我唯一的选择)之外,还有什么工具可以做到这一点?

没有

没有很好的方法可以通过列表理解来做到这一点,这不是他们的目的。列表理解的目的是为 maps 和 filters 提供一个更具可读性的替代方案,但事实并非如此,因此不可能以明智的方式做到这一点。

考虑到这不是我推荐的一段代码,出于上面评论和其他答案中讨论的原因,这种理解应该比 for 循环更快:

fibonacci = [0,1]
deque((fibonacci.append(fibonacci[-1]+fibonacci[-2]) for _ in range(10)), maxlen=0)

因为它使用生成器填充列表并丢弃结果(一个空队列,这是使用迭代器的最快推荐方式)

它产生:

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