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