在python中的2d列表中重新分配行/列表

时间:2011-12-08 03:20:35

标签: python list-comprehension

我试图在python中创建一个2d列表,其中x + 1,y + 1大小并且具有一些初始值。那些初始值是第一行包含数字0到'x',第一列包含数字0到'y'(包括两者)

假设x和y分别为3和4。

所以我去了:     listName = [range(0,x + 1)] *(y + 1);

这给了我一个有5行的2d列表,每行是一个数字0到3的列表,每行有4个索引(4列):

[[0, 1, 2, 3], 
 [0, 1, 2, 3], 
 [0, 1, 2, 3], 
 [0, 1, 2, 3], 
 [0, 1, 2, 3]]

据我所知,此时我有一个2d数组,但每行都是一个实例,所以如果我在每行中更改了任何值,那么所有行都会反映出这种变化。所以为了解决这个问题,我决定将每一行设置为一个新的唯一列表:

for row in listName:
    row = range(0, x + 1);

但是我注意到这似乎没有效果,我原来的名单即使我去了:

for row in listName:
    row = ["A", "B", "C", "D"];

在作业之前和之后打印显示“行”正在变化,但在循环之外,我在打印时会得到原始列表。尽管我已经找到了另一种方法来做我想做的事情,但我似乎无法弄清楚为什么会这样。有什么想法吗?

3 个答案:

答案 0 :(得分:1)

Slice-assign以修改现有列表,而不是仅重新绑定名称。

row[:] = ...

另外,你正在错误地构建它。

listName = [range(0, x + 1) for z in range(y + 1)]

答案 1 :(得分:0)

为名称分配列表时,您实际上是在实例化新列表。 Python有一个特殊的语法,允许你这样做:

row[:] = …

>>> listName = [range(0, x + 1)] * (y + 1);
>>> listName
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
>>> for row in listName:
...     row[:] = range(0, x+1)
... 
>>> listName
[[0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3], [0, 1, 2, 3]]
>>> for row in listName:
...     row[:] = range(0, x+6)
... 
>>> listName
[[0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2, 3, 4, 5, 6, 7, 8]]

但根据您的原始问题,您是否想要这样做?

>>> [range(0, x+1)] + [[i] + [0]*x for i in xrange(1, y+1)]
[[0, 1, 2, 3], [1, 0, 0, 0], [2, 0, 0, 0], [3, 0, 0, 0], [4, 0, 0, 0]]

答案 2 :(得分:0)

  

但是我注意到这似乎没有效果,我的原始列表

因为row = range(0, x + 1)并不意味着“row引用的事物的内容应替换为列表range(0, x + 1)的内容”;它的意思是“名称row将停止引用它当前所指的内容,而是引用列表range(0, x + 1)”。