乘法运算符应用于列表(数据结构) [英] Multiply operator applied to list(data structure)
问题描述
我正在阅读如何像计算机科学家一样思考,这是"Python编程"的介绍性文字;.
I'm reading How to think like a computer scientist which is an introductory text for "Python Programming".
我想弄清楚乘法运算符( *
)在应用于列表时的行为.
I want to clarify the behaviour of multiply operator (*
) when applied to lists.
考虑函数 make_matrix
def make_matrix(rows, columns):
"""
>>> make_matrix(4, 2)
[[0, 0], [0, 0], [0, 0], [0, 0]]
>>> m = make_matrix(4, 2)
>>> m[1][1] = 7
>>> m
[[0, 0], [0, 7], [0, 0], [0, 0]]
"""
return [[0] * columns] * rows
实际输出是
[[0, 7], [0, 7], [0, 7], [0, 7]]
make_matrix 的正确版本是:
def make_matrix(rows, columns):
"""
>>> make_matrix(3, 5)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> make_matrix(4, 2)
[[0, 0], [0, 0], [0, 0], [0, 0]]
>>> m = make_matrix(4, 2)
>>> m[1][1] = 7
>>> m
[[0, 0], [0, 7], [0, 0], [0, 0]]
"""
matrix = []
for row in range(rows):
matrix += [[0] * columns]
return matrix
make_matrix 的第一个版本失败的原因(如9.8中的书中所述)是
The reason why first version of make_matrix fails ( as explained in the book at 9.8 ) is that
...每行是其他行的别名...
我想知道为什么
[[0] * columns] * rows
导致 ...每行是其他行的别名...
但不是
[[0] * columns]
即为什么一行中的每个 [0]
都不是其他行元素的别名.
i.e. why each [0]
in a row is not an alias of other row element.
推荐答案
python中的所有对象都是对象,除非明确要求,否则python不会复制.
EVERYTHING in python are objects, and python never makes copies unless explicity asked to do so.
完成时
innerList = [0] * 10
您创建一个包含10个元素的列表,所有这些元素都引用相同的 int
对象 0
.
you create a list with 10 elements, all of them refering to the same int
object 0
.
由于整数对象是不可变的,因此您可以这样做
Since integer objects are immutable, when you do
innerList[1] = 15
您正在更改列表的第二个元素,以便它引用另一个整数 15
.由于 int
对象的不可变性,这种方法始终有效.
You are changing the second element of the list so that it refers to another integer 15
. That always works because of int
objects immutability.
这就是为什么
outerList = innerList * 5
将创建一个包含5个元素的 list
对象,每个对象都是对与上述相同的 innerList
的引用.但是由于 list
对象是可变的:
Will create a list
object with 5 elements, each one is a reference to the same innerList
just as above. But since list
objects are mutable:
outerList[2].append('something')
与以下相同:
innerList.append('something')
因为它们是对同一 list
对象的两个引用.因此,该元素最终位于该单个 list
中.它似乎是重复的,但事实是只有一个 list
对象,并且有很多引用.
Because they are two references to the same list
object. So the element ends up in that single list
. It appears to be duplicated, but the fact is that there is only one list
object, and many references to it.
对比一下,如果这样做
outerList[1] = outerList[1] + ['something']
在这里,您创建另一个 list
对象(将 +
与列表一起使用是显式副本),并且将对其的引用分配到 outerList
的第二个位置.如果您以这种方式添加"元素(不是真正地添加,而是创建了另一个列表),则 innerList
不会受到影响.
Here you are creating another list
object (using +
with lists is an explicit copy), and assigning a reference to it into the second position of outerList
. If you "append" the element this way (not really appending, but creating another list), innerList
will be unaffected.
这篇关于乘法运算符应用于列表(数据结构)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!