Re: Strange behavior related to value / reference

2009-10-28 Thread Lambda
On Oct 28, 10:40 am, Chris Rebert  wrote:
> On Tue, Oct 27, 2009 at 7:15 PM, Lambda  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.
>
> 
>
> > 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
-- 
http://mail.python.org/mailman/listinfo/python-list


Strange behavior related to value / reference

2009-10-27 Thread Lambda
I defined a function to raise a 2x2 matrix to nth power:

def matrix_power(m, n):
  result = m[:]
  print result is m

  for i in range(n - 1):
result[0][0] = result[0][0] * m[0][0] + result[0][1] * m[1][0]
result[0][1] = result[0][0] * m[0][1] + result[0][1] * m[1][1]
result[1][0] = result[1][0] * m[0][0] + result[1][1] * m[1][0]
result[1][1] = result[1][0] * m[0][1] + result[1][1] * m[1][1]
print result == m
print "result:", result, "m:", m
  return result

And the output:
False
True
result: [[1, 2], [2, 5]] m: [[1, 2], [2, 5]]
True
result: [[5, 20], [20, 425]] m: [[5, 20], [20, 425]]
True
result: [[425, 17000], [17000, 289180625]] m: [[425, 17000], [17000,
289180625]]

I find the matrix and m lists are always equal.
But these two lists are separate objects, right?
What's wrong with this code?

BTW, numpy has such a function, but it doesn't support really large
number.
Does numpy has some functions that support arbitrarily large number?
-- 
http://mail.python.org/mailman/listinfo/python-list


How to define a class that can act as dictionary key?

2009-09-15 Thread Lambda
Hi,

I'd like to define a class to use it as a dictionary key:

class dict_entry:
  def __init__(self, term = "", doc_freq = 0):
self.term = term
self.doc_freq = doc_freq

  def __cmp__(self, entry):
return isinstance(entry, dict_entry) and cmp(self.term,
entry.term)

  def __str__(self):
return term + ", " + str(docid)

And later...
entry = dict_entry(term, len(index[term]))
self.index[entry] = []

When I run it, it says "TypeError: unhashable instance"

It looks like I can't use the new class object as the dictionary key.
What should I do?
-- 
http://mail.python.org/mailman/listinfo/python-list