Something in the function tutorial confused me.

C

Carsten Haese

While it's correct that rebinding y will usually cause it to reference a
different object, this need not be true of assignment. The augmented
assignment operations do no necessarily rebind their left-hand operand -
that depends on the implementation of the relevant method in whatever
type is the subject of the augmented assignment.

An *assignment* to y therefore *usually* rebinds the name y to point to
a different value.

You are certainly correct within the bounds of the terminology you're
using, but I think some clarifications are necessary.

The language reference draws a clear distinction between assignments and
augmented assignments. In an augmented assignment, the difference
between a mutable target and a non-mutable target is indeed of utmost
relevance. However, drawing this distinction into a discussion about
what *assignments* will and won't do is confusing matters.

In a "plain" assignment of the form "name = expression", the mutability
of the object that the name is pointing to, if any, does not matter. I
believe that that was the point greg was trying to make when he objected
to this statement of yours:

"""
When the function starts out with None as y's value any assignment to y
causes it to reference a different value (since None is immutable). So
the next time the function is called y is pointing at the None that it
was pointing at the last time the function was called (since None cannot
be mutated).
"""

The problem is your ambiguous use of the word "assignment." In the sense
of the Language Reference, "any assignment to y" is a simple assignment
that always modifies a namespace and never modifies an object. In that
sense, the mutability of None really isn't the issue.

If you use the broader sense in which "assignment" includes augmented
assignments, the mutability of None does become relevant.

I agree that greg's delivery was unduly disrespectful, but I think he
was making a valid point.

Hope this helps clear up the confusion.

Best regards,
 
S

Steve Holden

Carsten said:
On Wed, 2007-08-08 at 08:52 -0400, Steve Holden wrote: [...]

The problem is your ambiguous use of the word "assignment." In the sense
of the Language Reference, "any assignment to y" is a simple assignment
that always modifies a namespace and never modifies an object. In that
sense, the mutability of None really isn't the issue.

If you use the broader sense in which "assignment" includes augmented
assignments, the mutability of None does become relevant.

I agree that greg's delivery was unduly disrespectful, but I think he
was making a valid point.

Hope this helps clear up the confusion.

Best regards,
And this is why we should all be using the term "binding", which is
normal in Python. I'll try to be more careful in future.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
N

Neil Cerutti

Carsten said:
On Wed, 2007-08-08 at 08:52 -0400, Steve Holden wrote: [...]
The problem is your ambiguous use of the word "assignment." In
the sense of the Language Reference, "any assignment to y" is
a simple assignment that always modifies a namespace and never
modifies an object. In that sense, the mutability of None
really isn't the issue.

If you use the broader sense in which "assignment" includes
augmented assignments, the mutability of None does become
relevant.

I agree that greg's delivery was unduly disrespectful, but I
think he was making a valid point.

Hope this helps clear up the confusion.

Best regards,

And this is why we should all be using the term "binding",
which is normal in Python. I'll try to be more careful in
future.

The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.

So Steve was both wrong and right, depending on the terminology.
I tend to think the world would be a better place if he'd been
right.
 
G

greg

Steve said:
For some reason your reply got right up my nose,

I'm sorry about that. Sometimes it's hard to judge the
level of experience with Python that a poster has. In
discussions about this particular topic, often it turns
out that the person is a newcomer to Python who is
using the wrong mental model of assignment, and your
comment about None being immutable suggested that this
is what was going on. If I was mistaken about that,
then I apologise.

While it may not have been what you meant, what you
*seemed* to be saying is that the result of a (plain)
assignment somehow depends on what was previously
bound to the name being assigned. I was just trying
to point out that this is not true.

The reason I suggested trying an example is that it
can be hard to talk about these things clearly when
you're not sure whether the words you're using, such
as "assignment", mean the same thing to the person
on the other end. The interpreter always interprets
things unambiguously.
 
S

Steve Holden

greg said:
I'm sorry about that. Sometimes it's hard to judge the
level of experience with Python that a poster has. In
discussions about this particular topic, often it turns
out that the person is a newcomer to Python who is
using the wrong mental model of assignment, and your
comment about None being immutable suggested that this
is what was going on. If I was mistaken about that,
then I apologise.
No worries. I've been subjected to far worse.
While it may not have been what you meant, what you
*seemed* to be saying is that the result of a (plain)
assignment somehow depends on what was previously
bound to the name being assigned. I was just trying
to point out that this is not true.
I must have expressed myself badly, then.
The reason I suggested trying an example is that it
can be hard to talk about these things clearly when
you're not sure whether the words you're using, such
as "assignment", mean the same thing to the person
on the other end. The interpreter always interprets
things unambiguously.
Sure. Don't worry, I was pretty sure it was as much me as you. Otherwise
I'd doubtless have been more obnoxious :)

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
M

Magnus Lycka

Lee said:
Hello,
I have a simple question. Say you have the following function:

def f(x, y = []): ....

But this, the code that "fixes" the list accumulation confounds me:
def f(x, y=None):
if y is None: y = [] ....

In other words, what's going on here? How is it that y accumulates
argument values between function calls in the first function, but
doesn't in the second one?

I think the important thing to understand here is the
distinction between names/variables and objects/values
in Python.

While you could interpret C code like this...

void f() {
...
int i = 5;
...
int j = i;
...
}

.... as "create a place in the namespace of the f function
where you can fit an integer value, and put the value 5
there. Later, create another place in the namespace of f
which is also big enough for an integer. Copy the contents
of the location named 'i', to the location named 'j'."

You would instead interpret this similar Python code...

def f():
...
i = 5
...
j = i
...

.... as "create an integer object with the value 5. Then
define a name/tag/variable in the namespace of function
f which refers to the integer object with the value 5.
Later, make a new name/tag/variable in the namespace of
f which refers to the same object (happens to be an
integer with the value 5) as i refers to."

The semantics is very different.

If you understand this, Python will seem much less magical,
and you will never ask meaningless questions as whether
Python uses call by reference or call by value.

It's all a matter of understanding that all the juicy bits
in the Python data model is in the actual values or objects.
That's the stuff with type safety, a location in memory,
qualities such as mutability etc. A "variable" is basically
just a reference to an arbitrary object in a particular
namespace. Assignments semantics is not about copying
data as in C, and it's nothing arbitrarily defined in
classes as in C++. It's all about deciding which object
a name refers to.
 
N

Neil Cerutti

It's all a matter of understanding that all the juicy bits in
the Python data model is in the actual values or objects.
That's the stuff with type safety, a location in memory,
qualities such as mutability etc. A "variable" is basically
just a reference to an arbitrary object in a particular
namespace.

Excellent post.

Languages like C tried to make the scope of names and the extent
of the objects they refer to be the same, probably for
efficiency. One nice property of this is that the two concepts
can be conflated into the simpler single idea of "variables".
It's simple, that is, until you create references. Then you can
get into complicated trouble by creating references to things
that may be destroyed. In Python names have lexical scope, while
the objects they refer to are eternal.
Assignments semantics is not about copying data as in C, and
it's nothing arbitrarily defined in classes as in C++. It's all
about deciding which object a name refers to.

Assignment semantics are not arbitrary in C++. You do have to
define them manually for new data types, but if you get it wrong
your code is pretty much useless. You are free to create your own
assignment semantics, as long as they match the semantics of the
built in types. Python has this property as well, though you're
limited to screwing up the "augmented assignment/arithmetic"
operators.
 
A

Alex Martelli

greg said:
I'm sorry about that. Sometimes it's hard to judge the
level of experience with Python that a poster has. In

Because of this, a Google search for

"<name> <surname>" python

may sometimes help; when you get 116,000 hits, as for "Steve Holden"
python, that may be a reasonable indication that the poster is one of
the world's Python Gurus (in fact, the winner of the 2007 Frank WIllison
Award -- congratulations, Steve!!!).


Alex
 
A

Alex Martelli

Neil Cerutti said:
The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.

Assignment *IS* "necessarily taking place"; if you try the augmented
assignment on something that DOESN'T support assignment, you'll get an
exception. Consider:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT, so tuples
don't allow a += on any of their items.

If you thought that += wasn't an assignment, this behavior and error
message would be very problematic; since the language reference ISN'T
confused and has things quite right, this behavior and error message are
perfectly consistent and clear.


Alex
 
N

Neil Cerutti

Neil Cerutti said:
The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.

Assignment *IS* "necessarily taking place"; if you try the augmented
assignment on something that DOESN'T support assignment, you'll get an
exception. Consider:
tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT,
so tuples don't allow a += on any of their items.

If you thought that += wasn't an assignment, this behavior and
error message would be very problematic; since the language
reference ISN'T confused and has things quite right, this
behavior and error message are perfectly consistent and clear.

Thanks for the correction. I was under the illusion that
sometimes augmented assignment would instead mutate the
object.
 
A

Aahz

Because of this, a Google search for

"<name> <surname>" python

may sometimes help; when you get 116,000 hits, as for "Steve Holden"
python, that may be a reasonable indication that the poster is one of
the world's Python Gurus (in fact, the winner of the 2007 Frank WIllison
Award -- congratulations, Steve!!!).

Sometimes that precise search pattern isn't appropriate, of course. ;-)
 
A

Aahz

Neil Cerutti said:
The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.

Assignment *IS* "necessarily taking place"; if you try the augmented
assignment on something that DOESN'T support assignment, you'll get an
exception. Consider:
tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT,
so tuples don't allow a += on any of their items.

If you thought that += wasn't an assignment, this behavior and
error message would be very problematic; since the language
reference ISN'T confused and has things quite right, this
behavior and error message are perfectly consistent and clear.

Thanks for the correction. I was under the illusion that sometimes
augmented assignment would instead mutate the object.

Although Alex is essentially correct, the situation is a bit more complex
and you are correct that augmented assignment allows the object to decide
whether to mutate in place. However, the critical part of Alex's point
is what you need to focus on: it's the *tuple* in Alex's example that
intercepts the assignment call, not the list contained in the tuple.

Obviously, you can easily work around it:
t = ([],)
l = t[0]
l += ['foo']
t
(['foo'],)

And this proves that you are correct about the list getting mutated in
place and reflected back in the tuple. Generally speaking, augmented
assignment with nested container objects is a Bad Idea IMO -- split out
the bits you want to work with.
 
S

Steve Holden

Aahz said:
Sometimes that precise search pattern isn't appropriate, of course. ;-)

Of course, Alex didn't mention that there are actually 117,000 hits, and
the last thousand have nothing to do with programming ;-)

Alex, thanks for your congratulations, as no public announcement has yet
been made (apart from at OSCON) I haven't mentioned the Frank Willison
Award until now. The certificate arrived this week, and I am humbled by
the honor.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
R

Roel Schroeven

Aahz schreef:
...
The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.
Assignment *IS* "necessarily taking place"; if you try the augmented
assignment on something that DOESN'T support assignment, you'll get an
exception. Consider:

tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT,
so tuples don't allow a += on any of their items.

If you thought that += wasn't an assignment, this behavior and
error message would be very problematic; since the language
reference ISN'T confused and has things quite right, this
behavior and error message are perfectly consistent and clear.
Thanks for the correction. I was under the illusion that sometimes
augmented assignment would instead mutate the object.

Although Alex is essentially correct, the situation is a bit more complex
and you are correct that augmented assignment allows the object to decide
whether to mutate in place. However, the critical part of Alex's point
is what you need to focus on: it's the *tuple* in Alex's example that
intercepts the assignment call, not the list contained in the tuple.

Obviously, you can easily work around it:
t = ([],)
l = t[0]
l += ['foo']
t
(['foo'],)

I'm missing something here, I think. As far as I can tell, the language
reference says that the target is evaluated before the augmented
assignment is performed. If that's the case, I don't see how the tuple
in Alex' example has anything to with it: the assignment is to the list,
not the tuple.

And watch this (Python 2.4.2):
>>> tup = ([],)
>>> tup[0] += ['zap']

Traceback (most recent call last):
File "<pyshell#10>", line 1, in -toplevel-
tup[0] += ['zap']
TypeError: object does not support item assignment

So far that's the same as Alex' example, but look at the value of the
tuple now:
(['zap'],)

Despite the TypeError, the list *has* changed.
 
A

Aahz

Aahz schreef:
Although Alex is essentially correct, the situation is a bit more complex
and you are correct that augmented assignment allows the object to decide
whether to mutate in place. However, the critical part of Alex's point
is what you need to focus on: it's the *tuple* in Alex's example that
intercepts the assignment call, not the list contained in the tuple.

Obviously, you can easily work around it:
t = ([],)
l = t[0]
l += ['foo']
t
(['foo'],)

I'm missing something here, I think. As far as I can tell, the language
reference says that the target is evaluated before the augmented
assignment is performed. If that's the case, I don't see how the tuple
in Alex' example has anything to with it: the assignment is to the list,
not the tuple.

And watch this (Python 2.4.2):
tup = ([],)
tup[0] += ['zap']

Traceback (most recent call last):
File "<pyshell#10>", line 1, in -toplevel-
tup[0] += ['zap']
TypeError: object does not support item assignment

So far that's the same as Alex' example, but look at the value of the
tuple now:
(['zap'],)

Despite the TypeError, the list *has* changed.

Yup! Here's why:
def foo(bar): bar[0] += ['zap'] ....
import dis
dis.dis(foo)
1 0 LOAD_FAST 0 (bar)
3 LOAD_CONST 1 (0)
6 DUP_TOPX 2
9 BINARY_SUBSCR
10 LOAD_CONST 2 ('zap')
13 BUILD_LIST 1
16 INPLACE_ADD
17 ROT_THREE
18 STORE_SUBSCR
19 LOAD_CONST 0 (None)
22 RETURN_VALUE

Notice the critical sequence: BINARY_SUBSCR, INPLACE_ADD, STORE_SUBSCR.
It has to work that way to allow this:
[8]

There's simply no way to get augmented assignment to work correctly with
both lists and tuples when you allow both mutable and immutable elements.
Someone will always get surprised, and overall with strings and numbers
being the canonical list elements, I think making augmented assignment
work correctly with lists and immutables was the best decision.

But the unfortunate side-effect is that you get the TypeError with
augmented assignment in tuples only after the mutation has been done.
 
R

Roel Schroeven

Aahz schreef:
def foo(bar): bar[0] += ['zap'] ...
import dis
dis.dis(foo)
1 0 LOAD_FAST 0 (bar)
3 LOAD_CONST 1 (0)
6 DUP_TOPX 2
9 BINARY_SUBSCR
10 LOAD_CONST 2 ('zap')
13 BUILD_LIST 1
16 INPLACE_ADD
17 ROT_THREE
18 STORE_SUBSCR
19 LOAD_CONST 0 (None)
22 RETURN_VALUE

Notice the critical sequence: BINARY_SUBSCR, INPLACE_ADD, STORE_SUBSCR.
It has to work that way to allow this:
[8]

There's simply no way to get augmented assignment to work correctly with
both lists and tuples when you allow both mutable and immutable elements.
Someone will always get surprised, and overall with strings and numbers
being the canonical list elements, I think making augmented assignment
work correctly with lists and immutables was the best decision.

Thank you, I get it now. With that disassembled code in mind I had
another look at the relevant section in the Language Reference; now I
have a much better understanding of what's really happening.

I used to interpret the target in 'The target is only evaluated once'
more like an L-value in C/C++. That's not correct, of course, but I
didn't understand exactly how wrong it was until now.
 
O

OKB (not okblacke)

Aahz said:
tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Obviously, you can easily work around it:
t = ([],)
l = t[0]
l += ['foo']
t
(['foo'],)

This is quite shocking to me, although after staring at the
documentation for a while I guess I understand it. But it seems to me
that the documentation is somewhat misleading on this point, where it
says:

"An augmented assignment evaluates the target (which, unlike normal
assignment statements, cannot be an unpacking) and the expression list,
performs the binary operation specific to the type of assignment on the
two operands, and assigns the result to the original target."

This sentence is phrased as though it is the whole story, but it
isn't, because the operation might not in fact wind up being an
assignment. Shouldn't there be an "except see below" or something
there, to alert the reader that in some cases a true assignment doesn't
occur? (I realize that the exception follows quite closely on the heels
of this sentence, but it doesn't follow immediately, and is separated by
a paragraph break and intervening material about the parallel to
unaugmented x = x + 1. On initial reading my tendency is to read the
end of the sentence quoted above, see a paragraph break and apparently
explanatory material, and go "oh, okay, I now have the full
specification of this syntax" when in fact I don't.)

--
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown
 
R

Roel Schroeven

OKB (not okblacke) schreef:
Aahz said:
tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
Obviously, you can easily work around it:
t = ([],)
l = t[0]
l += ['foo']
t
(['foo'],)

This is quite shocking to me, although after staring at the
documentation for a while I guess I understand it. But it seems to me
that the documentation is somewhat misleading on this point, where it
says:

"An augmented assignment evaluates the target (which, unlike normal
assignment statements, cannot be an unpacking) and the expression list,
performs the binary operation specific to the type of assignment on the
two operands, and assigns the result to the original target."

This sentence is phrased as though it is the whole story, but it
isn't, because the operation might not in fact wind up being an
assignment.

The way I understand this now, the assignment really always is an
assignment.

1.
- For immutable objects, the 'binary operation specific to the type of
assignment on the two operands' doesn't modify any object, but only
returns a new object which is the result of the operation.
- For mutable objects that support the inplace-version of the
operator, the operator modifies the object and then returns it.
3. In both cases that result is assigned to the target. In the second
case the object was already modified so the assignment doesn't
accomplish very much, but it still happens.

That explains why "tup[0] += ['zap']" both has an effect (tup[0] now
contains 'zap') and raises an exception: tup[0] is modified because it
is a list and lists support inplace addition, but the assignment fails
because tuples don't support item assignment.
 
G

Gregory D. Weber

Neil said:
Neil Cerutti said:
The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.
Assignment *IS* "necessarily taking place"; if you try the augmented
assignment on something that DOESN'T support assignment, you'll get an
exception. Consider:
tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT,
so tuples don't allow a += on any of their items.

If you thought that += wasn't an assignment, this behavior and
error message would be very problematic; since the language
reference ISN'T confused and has things quite right, this
behavior and error message are perfectly consistent and clear.

Thanks for the correction. I was under the illusion that
sometimes augmented assignment would instead mutate the
object.

I too thought += was an assignment. And it bit me very painfully a few weeks ago.

If it's an assignment, then wouldn't "x += y" mean the same thing as "x = x + y"?

If so, why does an assignment to variable a, below, have the *side effect* of changing variable b ... ?
a = [1, 2, 3]
b = a
b [1, 2, 3]
a += [4]
a [1, 2, 3, 4]
b
[1, 2, 3, 4]

.... but using the "x = x + y" style, the assignment to variable c, below, does *not* have a side effect on variable d (as indeed it should not!)?
c = [1, 2, 3]
d = c
d [1, 2, 3]
c = c + [4]
c [1, 2, 3, 4]
d [1, 2, 3]
 
R

Roel Schroeven

Gregory D. Weber schreef:
Neil said:
...
The Python Language Reference seems a little confused about the
terminology.

3.4.7 Emulating numeric types
6.3.1 Augmented assignment statements

The former refers to "augmented arithmetic operations", which I
think is a nice terminology, since assignment is not necessarily
taking place. Then the latter muddies the waters.
Assignment *IS* "necessarily taking place"; if you try the augmented
assignment on something that DOESN'T support assignment, you'll get an
exception. Consider:

tup=([],)
tup[0] += ['zap']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Tuples don't support item ASSIGNMENT, and += is an ASSIGNMENT,
so tuples don't allow a += on any of their items.

If you thought that += wasn't an assignment, this behavior and
error message would be very problematic; since the language
reference ISN'T confused and has things quite right, this
behavior and error message are perfectly consistent and clear.
Thanks for the correction. I was under the illusion that
sometimes augmented assignment would instead mutate the
object.

I too thought += was an assignment. And it bit me very painfully a few weeks ago.

It is an assignment, but not only an assignment: first either the
creation of a new object (in case of immutable objects) or the
modification of an existing object (in case of mutable objects), than an
assignment.
If it's an assignment, then wouldn't "x += y" mean the same thing as "x = x + y"?

No:
- x += y, x is only evaluated once
- in x += y, the operation is performed in-place if possible, meaning
that (quoting from the language reference): rather than creating a new
object and assigning that to the target, the old object is modified instead
If so, why does an assignment to variable a, below, have the *side effect* of changing variable b ... ?
a = [1, 2, 3] -> A list is created and assigned to a
b = a -> That list is also assigned to b
b [1, 2, 3]
a += [4]
-> The list is modified (the list [4] is added to it) and assigned to a.
It was already assigned to a, so that assignment doesn't do very much in
this case. But it is performed.
-> Both a and b are still bound to the original (but now modified) list
object
... but using the "x = x + y" style, the assignment to variable c, below, does *not* have a side effect on variable d (as indeed it should not!)?
c = [1, 2, 3] -> A list is created and assigned to c
d = c -> That list is also assigned to d
d [1, 2, 3]
c = c + [4]
-> A new list object is created (the sum of the original one and the
list [4]) and assigned to c
[1, 2, 3, 4]
-> c is now bound to the new list object
[1, 2, 3]
-> ... while d is still bound to the original list object


I hope this clears up things a bit...
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top