Newbie question: Allocation vs references

J

Jan Danielsson

Hello all,

Behold:

----------
a = [ 'Foo', 'Bar' ]
b = [ 'Boo', 'Far' ]
q = [ a, b ]

print q[0][0]
print q[1][1]

a[0] = 'Snoo'
b[1] = 'Gnuu'

print q[0][0]
print q[1][1]
----------

This will output:
Foo
Far
Snoo
Gnuu

I assume it does so because q stores _references_ to a and b. How
would do I do if I want to copy the list? I.e. I want the output from
the code above to be:

Foo
Far
Foo
Far

...even if a[0] = 'Snoo' and b[1] = 'Gnuu' remain where they are.

Or, better yet, how do I store a and b in q, and then tell Python
that I want a and b to point to new lists, without touching the contents
in q?

C equivalent of what I want to do:
-----------
a = calloc(n, size);
prepare(a)

q[0] = a;

a = calloc(n, size); // new list; 'q' is unaffected if I change 'a'
-----------
 
R

rzed

Hello all,

Behold:

----------
a = [ 'Foo', 'Bar' ]
b = [ 'Boo', 'Far' ]
q = [ a, b ]

print q[0][0]
print q[1][1]

a[0] = 'Snoo'
b[1] = 'Gnuu'

print q[0][0]
print q[1][1]
----------

This will output:
Foo
Far
Snoo
Gnuu

I assume it does so because q stores _references_ to a and b.
How
would do I do if I want to copy the list? I.e. I want the output
from the code above to be:

If your original assigment to q were:
q = [ a[:], b[:] ]
.... you would have copies of a and b, so that:
a = [ 'Foo', 'Bar' ]
b = [ 'Boo', 'Far' ]
q = [ a[:], b[:] ]
print q[0][0] Foo
print q[1][1] Far

a[0] = 'Snoo'
b[1] = 'Gnuu'

print q[0][0] Foo
print q[1][1]
Far

Foo
Far
Foo
Far

..even if a[0] = 'Snoo' and b[1] = 'Gnuu' remain where they are.

Or, better yet, how do I store a and b in q, and then tell
Python
that I want a and b to point to new lists, without touching the
contents in q?

That's easier:
a = [ 'Foo', 'Bar' ]
b = [ 'Boo', 'Far' ]
q = [a,b]
a = ['Splee','Hoongk']
b = ['Blik','Poit']
print q[0][0] Foo
print q[1][1]
Far

You've stuck the 'a' and 'b' labels on new objects this way. The
original objects would vanish except that there is still a reference
to them through the 'q' list.
C equivalent of what I want to do:
-----------
a = calloc(n, size);
prepare(a)

q[0] = a;

a = calloc(n, size); // new list; 'q' is unaffected if I change
'a' -----------
 
S

Stian =?iso-8859-1?Q?S=F8iland?=

a = [ 'Foo', 'Bar' ]
b = [ 'Boo', 'Far' ]
q = [ a, b ]
Or, better yet, how do I store a and b in q, and then tell Python
that I want a and b to point to new lists, without touching the contents
in q?

There are several ways to create a copy of a list:

a1 = a[:] # new copy, sliced from 0 to end
a2 = list(a) # create a new list object out of any sequence
import copy
a3 = copy.copy(a) # use the copy module


So you could do for example:

q1 = [ list(a), list(b) ]
q2 = [ a[:], b[:] ]
q3 = [ list(x) for x in (a,b)]


Note that the copy module also has a function deepcopy that will make
copies at all levels. So if you had:

q = [a,b]
q1 = copy.deepcopy(q2)


every list in q1, even the inner "a" and "b" will be new copies. Note
that non-mutables such as "Foo" and "Bar" are NOT copied, but as they
cannot be changed, that doesn't matter.

--
Stian Søiland Work toward win-win situation. Win-lose
Trondheim, Norway is where you win and the other lose.
http://soiland.no/ Lose-lose and lose-win are left as an
exercise to the reader. [Limoncelli/Hogan]
Og dette er en ekstra linje
 
S

Steven Bethard

Stian said:
There are several ways to create a copy of a list: [snip]
a2 = list(a) # create a new list object out of any sequence

I'll just point out that FWIW, this is by far my favorite idiom of the
ones offered because it applies to pretty much all the builtin container
types:

py> d = {1:42, -37:0}
py> d2 = dict(d)
py> d == d2, d is d2
(True, False)
py> s = set(['a', 'd', 'e'])
py> s2 = set(s)
py> s == s2, s is s2
(True, False)
py> L = [3.14, 0.707]
py> L2 = list(L)
py> L == L2, L is L2
(True, False)

STeVe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top