Python中的2D列表重复随机数分配

时间:2019-03-20 14:13:40

标签: python python-3.x memory arraylist reference

抱歉,我确定这个问题已经出现,但似乎没有一个例子适用。

我正在尝试创建2D列表(4 x 100),该列表为每行的不同范围分配随机值。

import random
size_of_meadow = 100
no_of_flowers = 100
no_of_flower_types = 3

flower = [[0] * 5] * no_of_flowers

for row in range(no_of_flowers):
    flower[row][0] = random.randint(0, size_of_meadow - 1)  # x coord
    flower[row][1] = random.randint(0, size_of_meadow - 1)  # y coord
    flower[row][2] = random.randint(1, no_of_flower_types)
if random.randint(0, 100) < 5:
    flower[row][3] = 1
else:
    flower[row][3] = 0

print(flower[0][0])
print(flower[0][1])
print(flower[0][2])
print(flower[0][3])
print(" ")
print(flower[1][0])
print(flower[1][1])
print(flower[1][2])
print(flower[1][3])
# Sorry the above isn't in a for loop

输出只为2D列表的每一行显示相同的数字集...

输出:

29
21
2
0

29
21
2
0

我是python的新手,我知道我必定会缺少一些基本知识,但是经过很多反复尝试之后,我仍未弄清楚,对您有所帮助。

谢谢

3 个答案:

答案 0 :(得分:3)

通过使用[[0] * 5] * no_of_flowers,您将创建100个对同一列表的引用。这意味着内存中只有只有一行

修改行时,如果影响到内存中的行,并且由于所有其他“行”都引用了该行,则它们将仅使用最新的内存中的列表。

为避免出现这种情况,您可以使用:

flower = [[0 for _ in range(5)] for _ in range(no_of_flowers)]

================================================ ==========================

您可以找到一个example and explanation in wtfpython

# Let's initialize a row
row = [""]*3 #row i['', '', '']
# Let's make a board
board = [row]*3

输出:

>>> board
[['', '', ''], ['', '', ''], ['', '', '']]
>>> board[0]
['', '', '']
>>> board[0][0]
''
>>> board[0][0] = "X"
>>> board
[['X', '', ''], ['X', '', ''], ['X', '', '']]

说明:

初始化row变量时,此可视化解释了内存中发生的情况。

enter image description here

board通过乘以row进行初始化时,这就是内存内部发生的情况(每个元素board[0]board[1]和{{1} }是对board[2]所引用的同一列表的引用

enter image description here

我们可以通过不使用row变量来生成row来避免这种情况。 (在this问题中提出)。

board

答案 1 :(得分:2)

您有一个包含100倍相同列表的列表

a=[0,0,0]
flower=[a,a,a,a,...]

更好的解决方案是

import random

size_of_meadow = 100
no_of_flowers = 100
no_of_flower_types = 3

flower = []

for row in range(no_of_flowers):
  flower.append([random.randint(0, size_of_meadow-1),
      random.randint(0, size_of_meadow-1),
      random.randint(1, no_of_flower_types),
      1 if random.randint(0, 100) < 5 else 0])

print(flower[0][0])
print(flower[0][1])
print(flower[0][2])
print(flower[0][3])
print(" ")
print(flower[1][0])
print(flower[1][1])
print(flower[1][2])
print(flower[1][3])
# Sorry the above isn't in a for loop

但是造花机会更好

答案 2 :(得分:2)

嘿,@ Lee说的没错,但让我详细说明

>>> flower = [[0] * 5] * 100
>>> flower[0]
[0, 0, 0, 0, 0]
>>> flower[1]
[0, 0, 0, 0, 0]
>>> id(flower[0])
4354853640
>>> id(flower[1])
4354853640

在这里您可以看到每个子列表将指向内存中的相同位置

我会使用这种方法:

flower = [[None for _ in range(5)] for _ in range(no_of_flowers)] 

>>> id(flower[0])
4354853832
>>> id(flower[1])
4354854600