简体   繁体   English

Python 2D 列表初始化问题

[英]Python 2D list initialisation issue

I was looking at initialising a 2D list in python using grid = [['x']*4]*6 essentially to create a 2D list with six rows with four x's.我正在考虑使用grid = [['x']*4]*6在 python 中初始化一个二维列表,本质上是为了创建一个带有四个 x 的六行的二维列表。 So, I hoped it would be the same as this approach:所以,我希望它与这种方法相同:

grid2 = [['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x']]

To check they are the same, I used print(grid == grid2) , which python reports as True.为了检查它们是否相同,我使用了print(grid == grid2) ,python 报告为 True。

Next, I would like to assign grid[0][0] ='O' , to change the first 'x' to 'O', but I have a different outcome based on whether I initialised using the method used for grid and grid2.接下来,我想分配grid[0][0] ='O' ,将第一个 'x' 更改为 'O',但根据我是否使用用于 grid 和 grid2 的方法进行初始化,我有不同的结果. The grid = [['x']*4]*6 method changes the first element of each list in the 2D array, while the longer initialisation method does what I want, it changes just the x at row & column = 0. I do not understand why it is not the same? grid = [['x']*4]*6方法更改二维数组中每个列表的第一个元素,而较长的初始化方法可以满足我的要求,它只更改行和列处的 x = 0。我不明白为什么不一样? I am sure there is someone out there who can explain this to me because I am mystified by this, it might be obvious, but I cannot spot it.我确信有人可以向我解释这一点,因为我对此感到困惑,这可能很明显,但我无法发现它。 My test code is below: Thanks!我的测试代码如下:谢谢!

#change identifier names between grid and grid2 to test. i.e change grid to grid2, vice versa. See the difference in behaviour? 


grid2 = [['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x']]
grid = [['x']*4]*6

print(grid == grid2)

print(grid)
print(grid2)

print()

for r in grid:
  for c in r:
    print(c, end = " ")
  print()



grid[0][0] ='O' # This behaves differently depending on whether I use grid or grid2

print()

for r in grid:
  for c in r:
    print(c, end = " ")
  print()

This is not the same because grid initialization creates 4-elements list once and keep 6 references to this list.这不一样,因为网格初始化一次创建了 4 个元素的列表,并保留了对这个列表的 6 个引用。

grid2 is list containing 6 different lists. grid2 是包含 6 个不同列表的列表。

You can check this using id method which provides identifier of object:您可以使用提供对象标识符的 id 方法进行检查:

In [8]: id(grid[0])                                                                                                                                                                                                
Out[8]: 139751930768584

In [9]: id(grid[1])                                                                                                                                                                                                
Out[9]: 139751930768584

In [10]: id(grid[2])                                                                                                                                                                                               
Out[10]: 139751930768584

In [11]: id(grid[3])                                                                                                                                                                                               
Out[11]: 139751930768584

In [12]: id(grid2[0])                                                                                                                                                                                              
Out[12]: 139751930891016

In [13]: id(grid2[1])                                                                                                                                                                                              
Out[13]: 139751931146824

In [14]: id(grid2[2])                                                                                                                                                                                              
Out[14]: 139751930890376

In [15]: id(grid2[3])                                                                                                                                                                                              
Out[15]: 139751930889032

As you can see grid[0] is same list as grid[1] because it has same id but grid2[0] has different id that grid2[1] because they are different objects.如您所见, grid[0] 与 grid[1] 列表相同,因为它具有相同的 id 但 grid2[0] 与 grid2[1] 具有不同的 id,因为它们是不同的对象。

You can initialize such 2D list this way:您可以通过以下方式初始化此类 2D 列表:

[['x' for j in range(4)] for i in range(6)]  
                                                                                                                              

Unfortunately, the list multiplication approach results in each sublist actually being the same exact object.不幸的是,列表乘法方法导致每个子列表实际上是相同的对象。 Here's one way around it:这是解决它的一种方法:

>>> grid = [['x' for _ in range(4)] for _ in range(6)]
>>> grid[0][0] = 'o'
>>> grid
[['o', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x'], ['x', 'x', 'x', 'x']]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM