为什么在列表上使用乘法运算符会创建指针列表

为什么在列表上使用乘法运算符会创建指针列表

本文介绍了为什么在列表上使用乘法运算符会创建指针列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

>>> rows = [['']*5]*5
>>> rows
[['', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', '']]
>>> rows[0][0] = 'x'

自然,我希望行成为:

[['x', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', ''], ['', '', '', '', '']]

相反,我得到了:

[['x', '', '', '', ''], ['x', '', '', '', ''], ['x', '', '', '', ''], ['x', '', '', '', ''], ['x', '', '', '', '']]

似乎行列表的元素是指向相同的旧[''] * 5列表的指针.为什么它会这样工作,这是Python功能吗?

It seems that elements of rows list are pointers to the same old ['']*5 list. Why does it work this way and is this a Python feature?

推荐答案

该行为并非特定于重复运算符(*).例如,如果使用+连接两个列表,则行为是相同的:

The behaviour is not specific to the repetition operator (*). For example, if you concatenate two lists using +, the behaviour is the same:

In [1]: a = [[1]]

In [2]: b = a + a

In [3]: b
Out[3]: [[1], [1]]

In [4]: b[0][0] = 10

In [5]: b
Out[5]: [[10], [10]]

这与以下事实有关:列表是对象,并且对象是通过引用存储的.当您使用*等时,引用会重复出现,因此您会看到这种行为.

This has to do with the fact that lists are objects, and objects are stored by reference. When you use * et al, it is the reference that gets repeated, hence the behaviour that you're seeing.

以下内容证明rows的所有元素都具有相同的标识(即CPython中的内存地址):

The following demonstrates that all elements of rows have the same identity (i.e. memory address in CPython):

In [6]: rows = [['']*5]*5

In [7]: for row in rows:
   ...:     print id(row)
   ...:
   ...:
15975992
15975992
15975992
15975992
15975992

下面的示例与您的示例等效,只不过它为行创建了五个不同的列表:

The following is equivalent to your example except it creates five distinct lists for the rows:

rows = [['']*5 for i in range(5)]

这篇关于为什么在列表上使用乘法运算符会创建指针列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-29 07:16