Velocity Reviews > Augument assignment versus regular assignment

# Augument assignment versus regular assignment

nagy
Guest
Posts: n/a

 07-08-2006
I do the following. First create lists x,y,z. Then add an element to x
using the augumented assignment operator. This causes all the other
lists to be changed also.
But if I use the assignment x=x+[4] instead of using the augumented
assignment, the y and z lists do not change.
Why is that?
This does not happen when I work with integer data type for example, as
shown below.

Nagy

>>> x=y=z=[]
>>> x+=[2]
>>> x

[2]
>>> y

[2]
>>> z

[2]
>>> x=x+[4]
>>>
>>> x

[2, 4]
>>> y

[2]
>>> z

[2]
>>> a=b=4
>>> b

4
>>> a+=2
>>> a

6
>>> b

4

Kirk McDonald
Guest
Posts: n/a

 07-08-2006
nagy wrote:
> I do the following. First create lists x,y,z. Then add an element to x
> using the augumented assignment operator. This causes all the other
> lists to be changed also.
> But if I use the assignment x=x+[4] instead of using the augumented
> assignment, the y and z lists do not change.
> Why is that?
> This does not happen when I work with integer data type for example, as
> shown below.
>
> Nagy
>
>
>>>>x=y=z=[]

In this example, the '[]' creates a new list object. x, y, and z are all
set to reference that object.

>>>>x+=[2]

This does an "in-place" operation on that list, modifying (or
"mutating") the object directly.

>>>>x

>

> [2]
>
>>>>y

>
> [2]
>
>>>>z

>
> [2]
>
>>>>x=x+[4]

This creates a new list that is the concatenation of the list created
above (the list [2]) with a new list (the list [4]). This brand new list
is bound to the name 'x'. The names 'y' and 'z' are left unchanged. That
is, they still point to the original list.

>>>>
>>>>x

>
> [2, 4]
>
>>>>y

>
> [2]
>
>>>>z

>
> [2]
>
>>>>a=b=4

This binds the names 'a' and 'b' to the integer object 4.

>>>>b

>
> 4
>
>>>>a+=2

This attempts to mutate the integer object 4, by adding 2 to it.
However, numbers in Python are immutable, and so the in-place operation
fails. Thus, it creates a new integer object equal to 6 (actually,
CPython keeps a cache of certain smaller integer objects and reuses
them, but this does not matter in practice). This new integer object is
bound to the name 'a'. The name 'b' remains bound to the original 4 object.

>>>>a

>
> 6
>
>>>>b

>
> 4
>

nagy
Guest
Posts: n/a

 07-08-2006
Thanks, Kirk.
I considered the += as only a shorthand notation for the assignment
operator.
Since for lists + is simply a concatetation, I am not sure it x=x+[2]
is creating a brand
new list. Could you refer me to any documentation on this?
Thanks,
Nagy
Kirk McDonald wrote:
> nagy wrote:
> > I do the following. First create lists x,y,z. Then add an element to x
> > using the augumented assignment operator. This causes all the other
> > lists to be changed also.
> > But if I use the assignment x=x+[4] instead of using the augumented
> > assignment, the y and z lists do not change.
> > Why is that?
> > This does not happen when I work with integer data type for example, as
> > shown below.
> >
> > Thanks for your help
> > Nagy
> >
> >
> >>>>x=y=z=[]

>
> In this example, the '[]' creates a new list object. x, y, and z are all
> set to reference that object.
>
> >>>>x+=[2]

>
> This does an "in-place" operation on that list, modifying (or
> "mutating") the object directly.
>
> >>>>x

> >

>
> > [2]
> >
> >>>>y

> >
> > [2]
> >
> >>>>z

> >
> > [2]
> >
> >>>>x=x+[4]

>
> This creates a new list that is the concatenation of the list created
> above (the list [2]) with a new list (the list [4]). This brand new list
> is bound to the name 'x'. The names 'y' and 'z' are left unchanged. That
> is, they still point to the original list.
>
> >>>>
> >>>>x

> >
> > [2, 4]
> >
> >>>>y

> >
> > [2]
> >
> >>>>z

> >
> > [2]
> >
> >>>>a=b=4

>
> This binds the names 'a' and 'b' to the integer object 4.
>
> >>>>b

> >
> > 4
> >
> >>>>a+=2

>
> This attempts to mutate the integer object 4, by adding 2 to it.
> However, numbers in Python are immutable, and so the in-place operation
> fails. Thus, it creates a new integer object equal to 6 (actually,
> CPython keeps a cache of certain smaller integer objects and reuses
> them, but this does not matter in practice). This new integer object is
> bound to the name 'a'. The name 'b' remains bound to the original 4 object.
>
> >>>>a

> >
> > 6
> >
> >>>>b

> >
> > 4
> >

Kirk McDonald
Guest
Posts: n/a

 07-08-2006
nagy wrote:
> Thanks, Kirk.
> I considered the += as only a shorthand notation for the assignment
> operator.
> Since for lists + is simply a concatetation, I am not sure it x=x+[2]
> is creating a brand
> new list. Could you refer me to any documentation on this?

Yes:

http://docs.python.org/ref/augassign.html
"An augmented assignment expression like x += 1 can be rewritten as x =
x + 1 to achieve a similar, but not exactly equal effect. In the
augmented version, x is only evaluated once. Also, when possible, the
actual operation is performed in-place, meaning that rather than
creating a new object and assigning that to the target, the old object

This behavior is only logical. Consider:

>>> x = [2]
>>> y = x + [4]

After these operations, we have two lists: x (the list [2]) and y (the
list [2, 4]). This is because the expression "x + [4]" creates a new
list. We then bind this new list to the name 'y', and leave the name 'x'
alone.

If we then say this:

>>> x = x + [6]

We are doing much the same operation. We are creating a new list (the
list [2, 6]), and binding it to the name 'x'. The list [2], previously
bound to 'x', is no longer bound to anything, so Python frees it.

The augmented assignment, as I went over previously, attempts to modify
the list object directly. Any names bound to the object (or any other
objects that reference the object) will see the changes.

-Kirk McDonald

Chris Lambacher
Guest
Posts: n/a

 07-08-2006
Looks like x=x+[2] creats a new list to me:
>>> b = [8,5,6]
>>> x = b
>>> x = x + [2]
>>> print b,x

[8, 5, 6] [8, 5, 6, 2]

-Chris
On Sat, Jul 08, 2006 at 11:56:11AM -0700, nagy wrote:
> Thanks, Kirk.
> I considered the += as only a shorthand notation for the assignment
> operator.
> Since for lists + is simply a concatetation, I am not sure it x=x+[2]
> is creating a brand
> new list. Could you refer me to any documentation on this?
> Thanks,
> Nagy
> Kirk McDonald wrote:
> > nagy wrote:
> > > I do the following. First create lists x,y,z. Then add an element to x
> > > using the augumented assignment operator. This causes all the other
> > > lists to be changed also.
> > > But if I use the assignment x=x+[4] instead of using the augumented
> > > assignment, the y and z lists do not change.
> > > Why is that?
> > > This does not happen when I work with integer data type for example, as
> > > shown below.
> > >
> > > Thanks for your help
> > > Nagy
> > >
> > >
> > >>>>x=y=z=[]

> >
> > In this example, the '[]' creates a new list object. x, y, and z are all
> > set to reference that object.
> >
> > >>>>x+=[2]

> >
> > This does an "in-place" operation on that list, modifying (or
> > "mutating") the object directly.
> >
> > >>>>x
> > >

> >
> > > [2]
> > >
> > >>>>y
> > >
> > > [2]
> > >
> > >>>>z
> > >
> > > [2]
> > >
> > >>>>x=x+[4]

> >
> > This creates a new list that is the concatenation of the list created
> > above (the list [2]) with a new list (the list [4]). This brand new list
> > is bound to the name 'x'. The names 'y' and 'z' are left unchanged. That
> > is, they still point to the original list.
> >
> > >>>>
> > >>>>x
> > >
> > > [2, 4]
> > >
> > >>>>y
> > >
> > > [2]
> > >
> > >>>>z
> > >
> > > [2]
> > >
> > >>>>a=b=4

> >
> > This binds the names 'a' and 'b' to the integer object 4.
> >
> > >>>>b
> > >
> > > 4
> > >
> > >>>>a+=2

> >
> > This attempts to mutate the integer object 4, by adding 2 to it.
> > However, numbers in Python are immutable, and so the in-place operation
> > fails. Thus, it creates a new integer object equal to 6 (actually,
> > CPython keeps a cache of certain smaller integer objects and reuses
> > them, but this does not matter in practice). This new integer object is
> > bound to the name 'a'. The name 'b' remains bound to the original 4 object.
> >
> > >>>>a
> > >
> > > 6
> > >
> > >>>>b
> > >
> > > 4
> > >

>
> --
> http://mail.python.org/mailman/listinfo/python-list

Frank Millman
Guest
Posts: n/a

 07-09-2006

nagy wrote:
> Thanks, Kirk.
> I considered the += as only a shorthand notation for the assignment
> operator.
> Since for lists + is simply a concatetation, I am not sure it x=x+[2]
> is creating a brand
> new list. Could you refer me to any documentation on this?
> Thanks,
> Nagy

My habit is to check the id.

>>> x = [1,2]
>>> id(x)

-1209327188
>>> x += [4]
>>> x

[1,2,4]
>>> id(x)

-1209327188
>>> x = x + [6]
>>> x

[1,2,4,6]
>>> id(x)

-1209334664

So it looks as if x += [] modifies the list in place, while x = x + []
creates a new list.

I am not sure if this is 100% guaranteed, as I have noticed in the past
that id's can be reused under certain circumstances. Perhaps one of the
resident gurus can comment.

Frank Millman

Dennis Lee Bieber
Guest
Posts: n/a

 07-09-2006
On 8 Jul 2006 23:02:04 -0700, "Frank Millman" <(E-Mail Removed)>
declaimed the following in comp.lang.python:

> I am not sure if this is 100% guaranteed, as I have noticed in the past
> that id's can be reused under certain circumstances. Perhaps one of the
> resident gurus can comment.
>

Since the ID tends to be the memory address (in CPython, at least),
it can be reused if all prior references to the object have gone away.

In

x = x + <anything>

the former reference to x doesn't go away until after the new binding of
x
--
Wulfraed Dennis Lee Bieber KD6MOG
http://www.velocityreviews.com/forums/(E-Mail Removed) (E-Mail Removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (E-Mail Removed))
HTTP://www.bestiaria.com/

Kirk McDonald
Guest
Posts: n/a

 07-09-2006
Frank Millman wrote:
> nagy wrote:
>
>>Thanks, Kirk.
>>I considered the += as only a shorthand notation for the assignment
>>operator.
>>Since for lists + is simply a concatetation, I am not sure it x=x+[2]
>>is creating a brand
>>new list. Could you refer me to any documentation on this?
>>Thanks,
>>Nagy

>
>
> My habit is to check the id.
>
>
>>>>x = [1,2]
>>>>id(x)

>
> -1209327188
>
>>>>x += [4]
>>>>x

>
> [1,2,4]
>
>>>>id(x)

>
> -1209327188
>
>>>>x = x + [6]
>>>>x

>
> [1,2,4,6]
>
>>>>id(x)

>
> -1209334664
>
> So it looks as if x += [] modifies the list in place, while x = x + []
> creates a new list.
>
> I am not sure if this is 100% guaranteed,

It is. This is true for any mutable type.

> as I have noticed in the past
> that id's can be reused under certain circumstances. Perhaps one of the
> resident gurus can comment.
>

Fredrik Lundh
Guest
Posts: n/a

 07-09-2006
Frank Millman wrote:

> So it looks as if x += [] modifies the list in place, while x = x + []
> creates a new list.

objects can override the += operator (by defining the __iadd__ method),
and the list type maps __iadd__ to extend. other containers may treat
+= differently, but in-place behaviour is recommended by the language
reference:

An augmented assignment expression like x += 1 can be rewritten as
x = x + 1 to achieve a similar, but not exactly equal effect. In
the augmented version, x is only evaluated once. Also, when possible,
the actual operation is performed in-place, meaning that rather than
creating a new object and assigning that to the target, the old object

</F>

Antoon Pardon
Guest
Posts: n/a

 07-10-2006
On 2006-07-09, Fredrik Lundh <(E-Mail Removed)> wrote:
> Frank Millman wrote:
>
>> So it looks as if x += [] modifies the list in place, while x = x + []
>> creates a new list.

>
> objects can override the += operator (by defining the __iadd__ method),
> and the list type maps __iadd__ to extend. other containers may treat
> += differently, but in-place behaviour is recommended by the language
> reference:
>
> An augmented assignment expression like x += 1 can be rewritten as
> x = x + 1 to achieve a similar, but not exactly equal effect. In
> the augmented version, x is only evaluated once. Also, when possible,
> the actual operation is performed in-place, meaning that rather than
> creating a new object and assigning that to the target, the old object

What does it mean that x is only evaluated once. I have an avltree module,
with an interface much like a directory. So I added print statements to
__setitem__ and __getitem__ and then tried the following code.

>>> from avltree import Tree
>>> t=Tree()
>>> t['a'] = 1

__setitem__, key = a
>>> t['a']

__getitem__, key = a
1
>>> t['a'] = t['a'] + 1

__getitem__, key = a
__setitem__, key = a
>>> t['a'] += 1

__getitem__, key = a
__setitem__, key = a
>>> t['b'] = []

__setitem__, key = b
>>> t['b'] = t['b'] + [1]

__getitem__, key = b
__setitem__, key = b
>>> t['b'] += [2]

__getitem__, key = b
__setitem__, key = b

So to me it seems that when we substitute t['a'] or t['b'] for x,
x is evaluated twice with the augmented version, just like it
is with the not augmented version.

--
Antoon Pardon