Strange behavior related to value / reference

Mark Dickinson dickinsm at gmail.com
Wed Oct 28 04:56:42 EDT 2009


On Oct 28, 8:24 am, Lambda <stephenh... at gmail.com> wrote:
> Thank you!
> Following is my final code:

Looks good, but are you sure about that word 'final'?  ;-)

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

I suggest using n // 2 instead of n / 2 here:  n // 2 always
does integer divsion (aka 'floor division' in Python), while
the behaviour of n/2 depends on whether you're using Python
2.x or 3.1, and (in 2.x) on whether anyone's put a 'from
__future__ import division' at the top of the file.

>   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

It's slightly more natural to build the list up as you go,
instead of creating a list of the right size and assigning
to its entries.  E.g.,

def matrix_mul(a, b):
    row0 = [a[0][0]*b[0][0] + a[0][1]*b[1][0],
            a[0][0]*b[0][1] + a[0][1]*b[1][1]]
    row1 = <similar>
    return [row0, row1]

Better still, use for loops to loop over the elements and
accumulate the sums, and then your code won't need rewriting
when you want to use it to take the power of 3-by-3 matrices.
And then check out the builtin 'sum' function, and consider
replacing some or all of the for loops with list
comprehensions (depending on personal taste)...

Not-so-final'ly yours,

Mark



More information about the Python-list mailing list