Simulating multi-dim array problem - OR - reference confusions

holger krekel pyth at devel.trillke.net
Tue Apr 16 19:21:42 EDT 2002


> 	I'm doing code that needs the functionality of multi-dimensional 
> 	arrays. I'm getting around this right now by using lists of lists, which 
>  seems to work right.  For instance:
> 
> >>> a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
> ...
> b = a[0]
>
> 	That b is actually a reference to the appropriate list in a, which 
> 	is just what I need.  

actually speaking in python semantics 

	b=a[0]

means that the "name 'b' is bound to 'a[0]'". Internally 
the reference count of the object a[0] is incremented.

the difference is that after you change b with e.g.

  b = ['bert'] 

a[0] will not have changed. You just changed the binding
of the name 'b' again -- not touching 'a' in any way
(except that the reference count of a[0] is decremented)! 

> [x, y, z, <PTR>]
> 	where <PTR> is set the way I described above, with b = a[0], or, in 
> 	this case, a[0][3] = a[10], etc.
> 
> 	Here's are my questions:
> 
> 	1) Am I going to get into trouble assuming (using the example above) 
> 	that b is basically a reference to the sublist a[0]?  I'm not clear how 
> sharing works in python.

see above. if you only work with the "binding" (not really sharing!) like

  b[i]=...  

then you are fine. 
 
> 	2) Is there a way I can print out the address of a "reference"?  In 
> particular I want some concise symbolic representation - like a memory 
> address, or a handle id, or SOMETHING - and not a verbatim 
> reconstruction of the list structure which is how python's "print" 
> function does it.  If I have elements containing references to elements 
> containing references to elements it's impossible to follow what's going 
> on with the chain.  I'd like to have it print something like:
> 
> [[x, y, z, 0x123123], [a, b, c, 0x123958], [q, w, e, 0x358481]]

you might want to work with a wrapper around rows to solve the two
issues:

class mrow:
    "read/write-wrapper for a row of a list"
    def __init__(self, mlist, row):
        self.mlist = mlist
        self.row   = row

    def get(self):
    	" get a reference 
        return self.mlist[self.row]

    def set(self, arg):
        self.mlist[self.row]=arg
        return self.get()

    def __repr__(self):
	" what you see when you print it """
        return 'row %d' % (self.row)

you can use it like this:

>>> li=[ [1,2,3], [4,5,6], [7,8,9]]  # as usual
>>>
>>> b = mrow(li,2)  
>>> print b
row 2
>>>
>>> for row in li:
...     row.append(b) # append the row reference
...
>>> print li
[[1, 2, 3, row 2], [4, 5, 6, row 2], [7, 8, 9, row 2]]
>>>
>>> print li[0][3].get()
[7, 8, 9, row 2]
>>>
>>> li[0][3].set( [42,23,5,mrow(li,0)])
[42, 23, 5, row 0]
>>> print li
[[1, 2, 3, row 2], [4, 5, 6, row 2], [42, 23, 5, row 0]]
>>>

hope that's understandable and what you want. if not just say so...

	holger





More information about the Python-list mailing list