如何将列表相乘并设置单个变量?

时间:2015-01-27 02:51:21

标签: python python-3.x

我尝试创建一个长列表,而不必每次都手动输入。我目前正在使用它(为了简单起见,用0代替更长的数字):

mylist = [[0]*5]*5

这是:

[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

打印每一行,此列表如下所示:

00000
00000
00000
00000
00000

当我尝试更改其中一个数字时(让我们说第一行和第一项),它会设置所有行'第一项。

mylist[0][0] = 1

打印每一行:

10000
10000
10000
10000
10000

如何设置我想要的项目?

2 个答案:

答案 0 :(得分:3)

您看到此行为是因为您已创建了一个列表mylst,其中包含五个相同列表副本。

您可以使用id来查看此内容,它会返回对象的唯一标识符:

In [1]: lst = [[0]*5]*5

In [2]: [id(sublst) for sublst in lst]
Out[2]: 
[139951176432584,
 139951176432584,
 139951176432584,
 139951176432584,
 139951176432584]

这是因为[0]*5为您提供了一个包含五个零的列表,但是将它乘以五会得到同一个列表的五个副本,而不是五个具有相同值的不同列表。

您可以使用列表推导来初始化原始列表来避免此行为:

In [3]: lst = [[0]*5 for _ in range(5)]

In [4]: [id(sublst) for sublst in lst]
Out[4]: 
[139951176420808,
 139951176419528,
 139951176419464,
 139951176419592,
 139951176324040]

作为一种风格问题,我宁愿避免使用*创建除简单平面列表之外的任何内容。为了保持一致性,我最初可能会创建您的列表:

In [3]: lst = [[0 for _ in range(5)] for _ in range(5)]

这种方法的优点是,如果以后需要更改任何内容,而不是0,则需要将值初始化为自定义对象(例如,Banana())。

如果没有这种方法,您可能会遇到与以前相同的问题,除非现在内部列表中的对象重复出现:

In [5]: class Banana(object):
   ...:     pass
   ...: 

In [6]: lst = [[Banana()]*5 for _ in range(5)]

In [7]: [[id(elem) for elem in sublst] for sublst in lst]
Out[7]: 
[[139951176414824,
  139951176414824,
  139951176414824,
  139951176414824,
  139951176414824],
 [139951176415272,
  139951176415272,
  139951176415272,
  139951176415272,
  139951176415272],
 [139951176414096,
  139951176414096,
  139951176414096,
  139951176414096,
  139951176414096],
 [139951176414432,
  139951176414432,
  139951176414432,
  139951176414432,
  139951176414432],
 [139951176415496,
  139951176415496,
  139951176415496,
  139951176415496,
  139951176415496]]

换句话说,0根据平面列表或其他方式工作的唯一原因是,拥有相同int对象的多个副本(以及其他对象)不是问题内置类型,如float),因为这些对象被视为不可变并按值进行比较。

答案 1 :(得分:0)

您不应该使用*运算符来控制列表,它会将相同的项目设置为所有列表。

使用

mylist = [[0 for n in range(5)] for _ in range(5)]
mylist[0][0] = 1

print(mylist)

输出:

[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]