I found the querk in my code:
a = [1, 2, 3];
b = a;
b.append(4);
b == [1, 2, 3, 4]; # As it should.
a == [1, 2, 3, 4]; # - Why?
One would think that b is a referance to a - however I know it's not.
Without changing a thing from above, the following is true:
b = [];
b.append(5);
a == [1, 2, 3, 4];
b == [5];
How do I avoid accedentaly modifying variables, is this a bug? If not
why not?
Jens Thiede.
By the way, living in South Africa, where we have 11 national
languages is nice although - as a result - the World does not know
what to think of us. :)
[Python] Variable Scope 2 -- Thanks for 1.
| Tweet |
|
Search Discussions
-
JCM at Jan 9, 2004 at 8:56 pm ⇧
Rather, a and b hold references to the same object--the list createdJens Thiede wrote:
I found the querk in my code:
a = [1, 2, 3];
b = a;
b.append(4);
b == [1, 2, 3, 4]; # As it should.
a == [1, 2, 3, 4]; # - Why?
One would think that b is a referance to a - however I know it's not.
by the expression [1, 2, 3].Without changing a thing from above, the following is true:Assignment rebinds variables to different objects, so b now holds a
b = [];
b.append(5);
a == [1, 2, 3, 4];
b == [5];
How do I avoid accedentaly modifying variables, is this a bug? If not
why not?
reference to the list created by the expression [].
-
Ian at Jan 9, 2004 at 9:03 pm ⇧
As assignment binds but doesn't copy, you might askOn Fri, 09 Jan 2004 20:56:26 +0000, JCM wrote:
Assignment rebinds variables to different objects, so b now holds a
reference to the list created by the expression [].
http://www.python.org/doc/faq/programming.html#how-do-i-copy-an-object-in-python
--IAN
-
Notice: Undefined variable: pl_u_link_beg in /home/whirl/sites/grokbase/root/www/public_html__www/cc/flow/tpc.php on line 831
Notice: Undefined variable: pl_u_link_end in /home/whirl/sites/grokbase/root/www/public_html__www/cc/flow/tpc.php on line 831
Notice: Undefined variable: pl_u_link_beg2 in /home/whirl/sites/grokbase/root/www/public_html__www/cc/flow/tpc.php on line 833
Irmen de Jong
Notice: Undefined variable: pl_u_link_end in /home/whirl/sites/grokbase/root/www/public_html__www/cc/flow/tpc.php on line 833
at Jan 9, 2004 at 9:01 pm ⇧
First: please remove the ; from the end of your lines...Jens Thiede wrote:
I found the querk in my code:
a = [1, 2, 3];
b = a;
b.append(4);b == [1, 2, 3, 4]; # As it should.It's not. a and b are both a name (or a reference to) the same
a == [1, 2, 3, 4]; # - Why?
One would think that b is a referance to a - however I know it's not.
list object [1,2,3]. (notice the subtle difference !)Without changing a thing from above, the following is true:It's not a bug. It's the way Python works :-)
b = [];
b.append(5);
a == [1, 2, 3, 4];
b == [5];
How do I avoid accedentaly modifying variables, is this a bug? If not
why not?
A very important concept with Python is that you don't have variable
assignment, but name binding. An "assignment statement" binds a name on an
object, and the object can be of any type. A statement like this:
age = 29
doesn't assign the value 29 to the variable age. Rather, it labels the integer
object 29 with the name age. The exact same object can be given many names,
that is, many different "variables" can refer to the same value object:
firstName = login = recordName = "phil"
All three names now refer to the same string object "phil". Because assignment
in Python works this way, there are also no (type)declarations. You can
introduce a new name when you want, where you want, and attach it to any
object (of any type), and attach it to another object (of any type) when you
feel like it. For instance, if the line above has been executed and we then do
login 030405
the name login now refers to an int object 20030405, while firstName and
recordName still refer to the old string "phil".
That's why b in your second example, is changed. b becomes a name for
a different list object (namely, the empty list []). a still refers to
the original list.
HTH,
--Irmen.
-
JCM at Jan 9, 2004 at 9:32 pm ⇧
Irmen de Jong wrote:
...A very important concept with Python is that you don't have variableI think this statement is misleading--it seems to imply the integer
assignment, but name binding. An "assignment statement" binds a name on an
object, and the object can be of any type. A statement like this:
age = 29
doesn't assign the value 29 to the variable age. Rather, it labels the integer
object 29 with the name age.
object is altered somehow. Personally I see no problem with saying
the value 29 is assigned to the variable age, so long as you
understand the semantics.
-
Duncan Booth at Jan 10, 2004 at 12:14 pm ⇧
JCM <joshway_without_spam at myway.com> wrote in
news:btn6ks$ada$1 at fred.mathworks.com:Irmen de Jong wrote:Be careful. The integer object is actually altered, at least in so far as
...A very important concept with Python is that you don't have variableI think this statement is misleading--it seems to imply the integer
assignment, but name binding. An "assignment statement" binds a name
on an object, and the object can be of any type. A statement like
this:
age = 29
doesn't assign the value 29 to the variable age. Rather, it labels
the integer object 29 with the name age.
object is altered somehow. Personally I see no problem with saying
the value 29 is assigned to the variable age, so long as you
understand the semantics.
its reference count (which is part of the object) is changed:11import sys
sys.getrefcount(29)12age = 29
sys.getrefcount(29)
>>>
--
Duncan Booth duncan.booth at suttoncourtenay.org.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure? -
Shalabh Chaturvedi at Jan 11, 2004 at 3:05 am ⇧
Off the orig topic, but I think this only happens for small numbersDuncan Booth wrote:
Be careful. The integer object is actually altered, at least in so far as
its reference count (which is part of the object) is changed:11import sys
sys.getrefcount(29)12age = 29
sys.getrefcount(29)
(optimization - only one object exists for small numbers in Python).2a = 101
sys.getrefcount(101)2b = 101
sys.getrefcount(101)
>>>
In other words:Truea = 29
b = 29
a is bFalsea = 101
b = 101
a is b
Of course, 'is' isn't useful when comparing int objects. For other
operations, the semantics are not affected anyway as int objects are
immutable.
--
Shalabh -
Francis Avila at Jan 9, 2004 at 9:09 pm ⇧
Jens Thiede wrote in message ...I found the querk in my code:Ordinarily I would write a big custom-made explaination complete with
a = [1, 2, 3];
b = a;
b.append(4);
b == [1, 2, 3, 4]; # As it should.
a == [1, 2, 3, 4]; # - Why?
One would think that b is a referance to a - however I know it's not.
examples. However:
http://starship.python.net/crew/mwh/hacks/objectthink.html
This is good enough.
--
Francis Avila -
Jens Thiede at Jan 11, 2004 at 6:45 pm ⇧
OK, thanks for sorting that out, but what do I replace in the
following to avoid referancing:
x = [[0]*5]*5
x is [[0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0]]
and after
x[0][0] = 1;
x is [[1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0]]
is there a shorthand way to avoid referance or do I have to use a loop
or:
x = [[0]*5]+[[0]*5]+[[0]*5]+[[0]*5]+[[0]*5]
which is obviously stupid to try and do when the second cofficiant is
large or a variable.
Help would be much appreciated,
Jens Thiede
-
Peter Otten at Jan 11, 2004 at 7:05 pm ⇧
[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,Jens Thiede wrote:
OK, thanks for sorting that out, but what do I replace in the
following to avoid referancing:
x = [[0]*5]*5
x is [[0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0]]
and after
x[0][0] = 1;
x is [[1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0]]
is there a shorthand way to avoid referance or do I have to use a loop
or:
x = [[0]*5]+[[0]*5]+[[0]*5]+[[0]*5]+[[0]*5]
which is obviously stupid to try and do when the second cofficiant is
large or a variable.x = [[0]*5 for i in range(5)]
x[0][0] = 1
x
0, 0, 0]]
or[[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,y = map(list, [[0]*5]*5)
y[0][0] = 1
y
0, 0, 0]]
>>>
Peter
-
Francis Avila at Jan 11, 2004 at 7:17 pm ⇧
Jens Thiede wrote in message ...OK, thanks for sorting that out, but what do I replace in theAh, the joy of list comprehensions!
following to avoid referancing:
x = [[0]*5]*5
x is [[0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0]]
and after
x[0][0] = 1;
x is [[1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0]][[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,x = [ [ 0 for i in range(5)] for j in range(5)]
x
0, 0, 0]][[1, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0,x[0][0] = 1
x
0, 0, 0]]
>>>
There are other ways, but using list comprehensions is the usual idiom now.
--
Francis Avila -
Francis Avila at Jan 11, 2004 at 7:20 pm ⇧
Francis Avila wrote in message <10038cpbu23hv93 at corp.supernews.com>...Jens Thiede wrote in message ...In my enthusiasm for list comprehensions I went too far. The inner loopOK, thanks for sorting that out, but what do I replace in theAh, the joy of list comprehensions!
following to avoid referancing:
x = [[0]*5]*5
x is [[0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,0,0,0]]
and after
x[0][0] = 1;
x is [[1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0], [1,0,0,0,0]]x = [ [ 0 for i in range(5)] for j in range(5)]
comp is unnecessary because ints are immutable. So [ [0]*5 for i in
range(5) ] is enough.
--
Francis Avila
Related Discussions
Discussion Navigation
| view | thread | post |
Discussion Overview
| group | python-list |
| categories | python |
| posted | Jan 9, '04 at 8:47p |
| active | Jan 11, '04 at 7:20p |
| posts | 12 |
| users | 8 |
| website | python.org |
