Strange behavior related to value / reference
Lambda
stephenhsu9 at gmail.com
Wed Oct 28 04:24:29 EDT 2009
On Oct 28, 10:40 am, Chris Rebert <c... at rebertia.com> wrote:
> On Tue, Oct 27, 2009 at 7:15 PM, Lambda <stephenh... at gmail.com> wrote:
> > I defined a function to raise a 2x2 matrix to nth power:
>
> > def matrix_power(m, n):
> > result = m[:]
>
> Note that this only copies the *outer* list. It does NOT copy any of
> the inner, nested lists, it just makes fresh *references* to them,
> which is what's causing your problem; the inner lists get shared, thus
> the 2D lists are almost the same list for practical purposes.
>
> You want:
> result = [row[:] for row in m]
> Which explicitly copies the inner lists.
>
> <snip>
>
> > I find the matrix and m lists are always equal.
> > But these two lists are separate objects, right?
>
> Right, but the *inner* list objects *are* the same in your code, and
> lists with the same contents (in this case, the same inner lists)
> compare as equal (==) but not identical (`is`). Remember that all
> lists in Python are 1-dimensional; "multidimensional" lists are merely
> by convention, hence you have to think a bit more carefully when
> working with them.
>
> Cheers,
> Chris
> --http://blog.rebertia.com
Thank you!
Following is my final code:
def matrix_power(m, n):
"""
Raise 2x2 matrix m to nth power.
"""
if n == 0: return [[1, 0], [0, 1]]
x = matrix_power(m, n / 2)
square = matrix_mul(x, x)
if n % 2 == 0:
return square
else:
return matrix_mul(m, square)
def matrix_mul(a, b):
result = [row[:] for row in a]
result[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0]
result[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1]
result[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0]
result[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1]
return result
More information about the Python-list
mailing list