在内联for循环初始化中引用列表?
我想写一些像这样的代码:
x = [0]
x = [x[i-1] for i in range(1,10)]
我知道这个例子没有什么实际意义。但我想知道在用这种方式初始化列表时,是否可以使用之前计算过的值。(也许可以用某种lambda表达式)
这是我实际需要的代码:
x = [(b[i] - sum([(a[i][j] * x[j]) for j in range(i)])) / a[i][i] for i in range(n)]
这当然会出现以下错误:
UnboundLocalError: local variable 'x' referenced before assignment
我知道有一种方法可以解决这个问题:
x = []
for i in range(n):
x.append((b[i] - sum([(a[i][j] * x[j]) for j in range(i)])) / a[i][i])
但我真的很想知道第一个方法是否有可能实现。
2 个回答
3
虽然我完全同意你想做的事情不是个好习惯,但其实有一种方法可以做到(算是吧)。比如,我们来看这个:
x = [1]
z = [x.append(x[i]*2) for i in range(10)]
现在自然我们会得到:
>>> print z
[None, None, None, None, None, None, None, None, None, None]
但是,x
保存了我们想要的值:
>>> print x
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
所以以类似的奇怪方式,你可以这样做:
x = [some_init_value]
[x.append((b[i] - sum([(a[i][j] * x[j]) for j in range(i)])) / a[i][i]) for i in range(n)]
注意,x
是就地修改的,我们并没有把列表推导的结果赋值给x
,因为列表推导会返回一堆None
。
我想强调的是,这种做法是不好的。好的编程习惯是,列表推导不应该有副作用(就像我们这里的情况)。
编辑:显然在 CPython 版本小于等于 2.6 时,你可以用这种“病态黑客”方法,列表推导会有一个隐藏的值。eryksun 为斐波那契数列提供了一个很棒的黑客方法:
fib = [[0,1][j] if j<2 else locals()['_[1]'][j-1] + locals()['_[1]'][j-2] for j in range(10)]
自然,这在 CPython 2.7 和 PyPy 上是行不通的。