乘法运算符应用于列表(数据结构) [英] Multiply operator applied to list(data structure)

查看:77
本文介绍了乘法运算符应用于列表(数据结构)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读如何像计算机科学家一样思考,这是"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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆