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

Python 如何将列表相乘并设置单个变量?,python,python-3.x,Python,Python 3.x,我正在尝试创建一个长列表,而不必每次手动键入。我目前正在使用这个(为了简单起见,将较长的数字替换为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, 0]] 打印每行时,此列表如下所示: 00000 00000 00000 00000 00000 当我尝试更改其中一个数字(比如第一行和第一项)时,它会设置所有行的第一项 mylist[0][0] = 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, 0, 0]]
打印每行时,此列表如下所示:

00000
00000
00000
00000
00000
当我尝试更改其中一个数字(比如第一行和第一项)时,它会设置所有行的第一项

mylist[0][0] = 1
打印每行:

10000
10000
10000
10000
10000

如何仅设置所需的项目?

您看到这种行为是因为您创建了一个列表,
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)]
这种方法的优点是,如果以后要将值初始化为自定义对象(例如,
Banana()
),而不是
0
,则无需更改任何内容

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

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
)不是问题,因为这些对象被视为不可变并按值进行比较。

您看到这种行为是因为您创建了一个列表,
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)]
这种方法的优点是,如果以后要将值初始化为自定义对象(例如,
Banana()
),而不是
0
,则无需更改任何内容

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

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
)不是问题,因为这些对象被视为不可变并按值进行比较。

您看到这种行为是因为您创建了一个列表,
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)]
这种方法的优点是,如果以后要将值初始化为自定义对象(例如,
Banana()
),而不是
0
,则无需更改任何内容

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

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
)不是问题,因为这些对象被视为不可变并按值进行比较。

您看到这种行为是因为您创建了一个列表,
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)]
这种方法的优点是,如果以后要将值初始化为自定义对象(例如,
Banana()
),而不是
0
,则无需更改任何内容

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

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
)有多个副本并不成问题,因为这些对象被视为不可变的,并进行比较