[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: shared reference ?



On Wed, Dec 08, 1999 at 04:56:33PM +0100, Egbert Bouwman wrote:
> Mijn bijdragen zullen de eerste tijd nog niet de gewenste 
> moeilijkheidsgraad hebben. Nog even geduld.

Fijn, dan kan ik ook nog wat uitleggen :)

> Hier het resultaat van een proef met geneste lists:
> 
> >>> Los=[[0,0,0],[0,0,0]]
> >>> Los[1][1]=7
> >>> Los
> [0,0,0],[0,7,0]]
> 
> Ik had niet anders verwacht. Maar nu:
> 
> >>> Mat=[[0] * 3] * 2
> >>> Mat
> [[0,0,0],[0,0,0]]  # ok
> >>> Mat[1][1]=7
> >>> Mat
> [[0,7,0],[0,7,0]]
> 
> Er wordt kennelijk met [0]*3 een list-object opgebouwd waarnaar 
> twee keer wordt verwezen.

Dat klopt. Je kopieert een reference naar de lijst [0]*3 die je opbouwt.

> Hoe had ik dit wel moeten doen ?
> En hoe kan ik deze valkuil vermijden ?

Je kunt iedere lijst apart opbouwen, dan hebben ze een andere reference.

bijv.
>>> Mat=[]
>>> for spam in range(2): 
...     Mat.append([0]*3)
...
>>> Mat
[[0,0,0],[0,0,0]] # Ok
>>> Mat[1][1]=7
>>> Mat
[[0,0,0],[0,7,0]] # Ook Ok

Of anders moet je de assignment anders doen, dat kan handig zijn als
veel rijen nooit veranderd worden, maar je moet wel een hele rij
kopieren als er iets in verandert:

>>> Mat = [[0]*100]*100
# (Mat[0], Mat[1], etc verwijzen nu allemaal naar dezelfde lijst)
>>> kopie = Mat[1][:]
# kopie is nu een *kopie* van Mat[1]!
>>> kopie[1] = 7
# alleen kopie verandert
>>> Mat[1] = kopie
# Mat[1] verwijst naar de nieuwe lijst, alle andere Mat[n] nog naar de oude

Als je meer dan 2D arrays hebt moet je ingewikkelder gaan kopieren.
Kijk dan eens naar de copy-module, vnl. copy.deepcopy.

Over het algemeen: alles is een reference. Raak er maar aan gewend.
-- 
Remco Gerlich,  scarblac@pino.selwerd.cx

Nederlandse Python mailinglist, python@nl.linux.org
archief: http://mail.nl.linux.org/python/