首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这段代码返回T矩阵的最后一行

为什么这段代码返回T矩阵的最后一行
EN

Stack Overflow用户
提问于 2016-07-24 17:54:55
回答 4查看 57关注 0票数 0
代码语言:javascript
复制
class Solution:
    """
    rotates, queries and stuff blah blah blah
    """
    def mains(self):
     pass


    def rotate(self,A):
     n = len(A[0])
     T = [[0]*n]*n 
     # the above part is erraneous probably, on individual initialization it works!
     for i in xrange(n):
        for j in xrange(n):
             T[i][j] = A[j][i]


     print T



p = Solution()
p.rotate([[1,2,3],[4,5,6],[7,8,9]])    

产出是[3,6,9,3,6,9,9,3,6,9]这不是转座子

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-07-24 18:00:00

这是因为[[0]*n]*n创建了一个大小为n的列表,其中填充了对同一个列表([0]*n)的引用,所以当您访问T[i][j]时,您使用的是相同的内存位置。

下面是一些不同设置的示例:

代码语言:javascript
复制
>>> T=[[0]*5]*5
>>> T
[[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]]
>>> T[0][0]=5
>>> T #goes nuts
[[5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0]]

>>> T=[[0 for _ in range(5)]]*5
>>> T
[[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]]
>>> T[0][0]=5
>>> T #goes wrong
[[5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0], [5, 0, 0, 0, 0]]

>>> T=[[0 for _ in range(5)] for _ in range(5)]
>>> T
[[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]]
>>> T[0][0]=5
>>> T #this is correct!
[[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]]

>>> T=[[0]*5 for _ in range(5)]
>>> T
[[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]]
>>> T[0][0]=5
>>> T #this is also correct!
[[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]]

在示例中,除了第一个示例之外,我使用的是清单理解,这是创建列表并同时填充数据的一种非常强大的方法。

票数 2
EN

Stack Overflow用户

发布于 2016-07-24 17:59:07

使用您的方法,相同的子列表重复n时间:

代码语言:javascript
复制
T = [[0]*n]*n 

因此,变化在它们之间同时反映。

相反,您应该像这样设置T

代码语言:javascript
复制
T = [[0]*n for _ in range(n)]

这将创建n独立的子列表。

票数 2
EN

Stack Overflow用户

发布于 2016-07-24 18:00:21

您被list实例的易变性所捕获。这里

代码语言:javascript
复制
T = [[0]*n]*n 

内部乘法创建对n实例的int引用。由于Python的int是不可变的,所以当您更改一个对象时,将在后台创建一个新的对象和一个新的引用。list是不同的。您的外部乘法将引用复制到相同的列表,即[0] * n。因为Python的列表是可变的,所以每当您通过一个引用更改它时,更改都会在所有引用中反映出来,因为它们都引用内存中的同一个对象。

例如:

代码语言:javascript
复制
a = b = 3
b = 4
print(a, b)  # 3 4

注意,可变对象发生了什么:

代码语言:javascript
复制
a = b = [1, 2, 3]
b[1] = 0
print(a, b)  # [1, 0, 3] [1, 0, 3]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38555034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档