为什么此代码返回T矩阵的最后一行

时间:2016-07-24 17:54:56

标签: python list

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],[3,6,9]],这不是转置

4 个答案:

答案 0 :(得分:1)

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

T = [[0]*n]*n 

所以变化会同时反映在他们身上。

您应该像这样设置T

T = [[0]*n for _ in range(n)]

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

答案 1 :(得分:1)

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

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

>>> 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]]

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

答案 2 :(得分:1)

你被list实例的可变性所困扰。这里

T = [[0]*n]*n 

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

例如:

a = b = 3
b = 4
print(a, b)  # 3 4

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

a = b = [1, 2, 3]
b[1] = 0
print(a, b)  # [1, 0, 3] [1, 0, 3]

答案 3 :(得分:0)

您还可以在循环时构建列表:

>>> T = []
>>> 
>>> for i in xrange(3):
        T.append([])
             for j in xrange(3):
                 T[i].append(l[j][i])


>>> T
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]