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]这不是转座子
发布于 2016-07-24 18:00:00
这是因为[[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]]在示例中,除了第一个示例之外,我使用的是清单理解,这是创建列表并同时填充数据的一种非常强大的方法。
发布于 2016-07-24 17:59:07
使用您的方法,相同的子列表重复n时间:
T = [[0]*n]*n 因此,变化在它们之间同时反映。
相反,您应该像这样设置T:
T = [[0]*n for _ in range(n)]这将创建n独立的子列表。
发布于 2016-07-24 18:00:21
您被list实例的易变性所捕获。这里
T = [[0]*n]*n 内部乘法创建对n实例的int引用。由于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]https://stackoverflow.com/questions/38555034
复制相似问题