a=([],); a[0]+=[1]

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Andrea Griffini

    a=([],); a[0]+=[1]

    When reading about python "warts" i stepped in this
    example I find quite puzzling:

    a = ( [] , )
    a[0] += [1]

    this gives an error, because a tuple cannot be
    modified. But if you print the content of "a"
    it will show it has indeed been modified.

    How can this happen ? if "+=" for list was called
    then no modification to the tuple was requested and
    so no error should have been raised; if instead "+"
    and "=" was executed then after a failing assignment
    the original list is safe... (or at least I thought
    so; if you type "a[0] = [2]" you get the error and
    "a" is not modified).

    Is there an explanation simpler than investigating
    on python sources ?

    Andrea
  • Duncan Booth

    #2
    Re: a=([],); a[0]+=[1]

    Andrea Griffini <agriff@tin.i t> wrote in
    news:7ff790taoj rrqka0trq9ltm82 g0ac95ria@4ax.c om:
    [color=blue]
    > When reading about python "warts" i stepped in this
    > example I find quite puzzling:
    >
    > a = ( [] , )
    > a[0] += [1]
    >
    > this gives an error, because a tuple cannot be
    > modified. But if you print the content of "a"
    > it will show it has indeed been modified.
    >
    > How can this happen ? if "+=" for list was called
    > then no modification to the tuple was requested and
    > so no error should have been raised; if instead "+"
    > and "=" was executed then after a failing assignment
    > the original list is safe... (or at least I thought
    > so; if you type "a[0] = [2]" you get the error and
    > "a" is not modified).
    >
    > Is there an explanation simpler than investigating
    > on python sources ?
    >[/color]

    += is implemented by calling the __iadd__ method (if it exists, otherwise
    __add__ is called). In either case the result of the method is then
    assigned to the destination.

    So what is happening here is that list.__iadd__ modifies the list in place,
    but then the attempt to assign the result into the tuple fails.

    Although __iadd__ extends the list in place this need not be true for all
    types. An object could have an implementation for inplace addition that
    actually creates a new object, so Python cannot optimise out the store.

    See http://groups.google.co.uk/groups?th...EBE%40noaa.gov
    for a (long) discussion of this topic.

    Comment

    Working...