RE: python assignment

Discussion in 'Python' started by Tim Peters, Jul 23, 2003.

  1. Tim Peters

    Tim Peters Guest

    [Tim]
    >> It would be very unusual (because bad design) for the __iadd__
    >> method of a mutable type to return a pre-existing object, though.


    [Juha Autero]
    > I'm confused. I thought that the idea of __iadd__ is that for
    > *mutable* types it modifies existing object instead of returning new
    > one.


    Bjorn added more appropriate words -- it would be bad design for the
    __iadd__ method of a mutable type to return a pre-existing object other than
    self.

    >>> a = [1, 2]
    >>> b = [1]
    >>> b += [2]


    While "a == b" must be true at this point, it would be a nightmare if "a is
    b" could be true at this point. For immutable types it doesn't matter:

    >>> a = (1, 2)
    >>> b = (1,)
    >>> b += (2,)


    It so happens that "a is b" is not true at this point under any Python
    released so far, but it could be true someday without causing harm.

    Sorry for the confusion!
    Tim Peters, Jul 23, 2003
    #1
    1. Advertising

  2. Tim Peters

    dan Guest

    "Tim Peters" <> wrote in message news:<>...
    > [Tim]

    ....
    > Bjorn added more appropriate words -- it would be bad design for the
    > __iadd__ method of a mutable type to return a pre-existing object other than
    > self.
    >
    > >>> a = [1, 2]
    > >>> b = [1]
    > >>> b += [2]

    >
    > While "a == b" must be true at this point, it would be a nightmare if "a is
    > b" could be true at this point. For immutable types it doesn't matter:
    >
    > >>> a = (1, 2)
    > >>> b = (1,)
    > >>> b += (2,)

    >
    > It so happens that "a is b" is not true at this point under any Python
    > released so far, but it could be true someday without causing harm.
    >
    > Sorry for the confusion!


    Ok, that makes sense to me. I still think it would be a good idea to
    put a section in the Tutorial -- perhaps under "for computer
    scientists and those who want to learn more" -- describing how Python
    binds names to objects.

    In particular, the fact that a list is a list of pointers, not the
    objects themselves, seems like an important point to make, even for
    relative newcomers.

    Here's the thing that tripped me up, and the solution I came up with,
    which I am now unsure of:

    #original code -- v[] is a list

    for x in range(n):
    temp = [x+y for y in range(3)] #or whatever
    v[x] = temp

    so I was quite surprised to find all members of v[] were in fact
    pointers to one object, temp[].

    My solution, which I'm worried about, was this:

    for x in range(n):
    temp = [x+y for y in range(3)] #or whatever
    v[x] = temp + [] #'assignment by copy'???

    So I'm still unclear as to whether an expression like temp+[] is
    defined as returning a new list or not. Seems like it might be
    undefined, since either way is arguably 'correct'.
    dan, Jul 25, 2003
    #2
    1. Advertising

  3. Tim Peters

    dan Guest

    er, my example in last post should have been:

    >>> for x in range(3):

    .... for y in range(3):
    .... temp[y] = x+y
    .... v[x] = temp
    ....
    >>> v

    [[2, 3, 4], [2, 3, 4], [2, 3, 4]] #Surprise! You're in Pythonville

    #fixed:

    >>> for x in range(3):

    .... for y in range(3):
    .... temp[y] = x+y
    .... v[x] = temp + []
    ....
    >>> v

    [[0, 1, 2], [1, 2, 3], [2, 3, 4]] #expected behavior

    but again the +[] looks funky in the morning light. Can I always
    assume that an operation of this sort will return a new object, even
    if it has no effect on one of the operands?

    I suppose a clearer fix would be v[x] = copy.copy(temp), eh?

    "Tim Peters" <> wrote in message news:<>...
    > [Tim]
    > >> It would be very unusual (because bad design) for the __iadd__
    > >> method of a mutable type to return a pre-existing object, though.

    >
    > [Juha Autero]
    > > I'm confused. I thought that the idea of __iadd__ is that for
    > > *mutable* types it modifies existing object instead of returning new
    > > one.

    >
    > Bjorn added more appropriate words -- it would be bad design for the
    > __iadd__ method of a mutable type to return a pre-existing object other than
    > self.
    >
    > >>> a = [1, 2]
    > >>> b = [1]
    > >>> b += [2]

    >
    > While "a == b" must be true at this point, it would be a nightmare if "a is
    > b" could be true at this point. For immutable types it doesn't matter:
    >
    > >>> a = (1, 2)
    > >>> b = (1,)
    > >>> b += (2,)

    >
    > It so happens that "a is b" is not true at this point under any Python
    > released so far, but it could be true someday without causing harm.
    >
    > Sorry for the confusion!
    dan, Jul 25, 2003
    #3
  4. Quoth dan:
    [...]
    > but again the +[] looks funky in the morning light. Can I always
    > assume that an operation of this sort will return a new object, even
    > if it has no effect on one of the operands?


    Afaik it's not documented, but I think you may safely assume that
    arithmetic on lists will always produce a new list, even in such
    cases as
    a_list + []
    1*a_list
    Having such expressions possibly return the existing object is a
    harmless optimization for immutable types, but would be madness
    for mutable objects such as lists. Guido is not mad. (A little
    eccentric sometimes, occasionally silly, and noticeably Dutch, but
    not mad.)

    > I suppose a clearer fix would be v[x] = copy.copy(temp), eh?


    Yes, that, or
    v[x] = list(temp)
    or
    v[x] = temp[:]
    according to taste. The latter is most common, I think.

    --
    Steven Taschuk
    "[T]rue greatness is when your name is like ampere, watt, and fourier
    -- when it's spelled with a lower case letter." -- R.W. Hamming
    Steven Taschuk, Jul 25, 2003
    #4
  5. Ray was tryin to follow the thread ...

    Dan was talking to Tim about something.
    (see below signature if your not following
    thread and want to know what it's about.)

    .... and Ray had a question.

    >[Dan to Tim paraphrased]
    >
    >My solution, which I'm worried about, was this:
    >
    > for x in range(n):
    > temp = [x+y for y in range(3)] #or whatever
    > v[x] = temp + [] #'assignment by copy'???
    >


    Ray's question = That last line "v[x] = temp + []",
    that's equivelent to "v.append(temp)", is it not?


    TIA
    Ray St.Marie


    Thread I got this from
    >"Tim Peters" <> wrote in message
    >news:<>...
    >> [Tim]

    >...
    >> Bjorn added more appropriate words -- it would be bad design for the
    >> __iadd__ method of a mutable type to return a pre-existing object other

    >than
    >> self.
    >>
    >> >>> a = [1, 2]
    >> >>> b = [1]
    >> >>> b += [2]

    >>
    >> While "a == b" must be true at this point, it would be a nightmare if "a is
    >> b" could be true at this point. For immutable types it doesn't matter:
    >>
    >> >>> a = (1, 2)
    >> >>> b = (1,)
    >> >>> b += (2,)

    >>
    >> It so happens that "a is b" is not true at this point under any Python
    >> released so far, but it could be true someday without causing harm.
    >>
    >> Sorry for the confusion!

    >
    >Ok, that makes sense to me. I still think it would be a good idea to
    >put a section in the Tutorial -- perhaps under "for computer
    >scientists and those who want to learn more" -- describing how Python
    >binds names to objects.
    >
    >In particular, the fact that a list is a list of pointers, not the
    >objects themselves, seems like an important point to make, even for
    >relative newcomers.
    >
    >Here's the thing that tripped me up, and the solution I came up with,
    >which I am now unsure of:
    >
    >#original code -- v[] is a list
    >
    > for x in range(n):
    > temp = [x+y for y in range(3)] #or whatever
    > v[x] = temp
    >
    >so I was quite surprised to find all members of v[] were in fact
    >pointers to one object, temp[].
    >
    >My solution, which I'm worried about, was this:
    >
    > for x in range(n):
    > temp = [x+y for y in range(3)] #or whatever
    > v[x] = temp + [] #'assignment by copy'???
    >
    >So I'm still unclear as to whether an expression like temp+[] is
    >defined as returning a new list or not. Seems like it might be
    >undefined, since either way is arguably 'correct'.
    >
    Raymond Arthur St. Marie II of III, Jul 25, 2003
    #5
  6. Tim Peters

    Terry Reedy Guest

    "dan" <> wrote in message
    news:...
    > >>> for x in range(3):

    > ... for y in range(3):
    > ... temp[y] = x+y
    > ... v[x] = temp + []
    > ...
    > >>> v

    > [[0, 1, 2], [1, 2, 3], [2, 3, 4]] #expected behavior
    >
    > but again the +[] looks funky in the morning light. Can I always
    > assume that an operation of this sort will return a new object, even
    > if it has no effect on one of the operands?
    >
    > I suppose a clearer fix would be v[x] = copy.copy(temp), eh?


    or add temp = [None]*3[] between 'for x' and 'for y' so you start with
    an explicitly new temp for each x loop.

    Terry J. Reedy
    Terry Reedy, Jul 25, 2003
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dan

    python assignment

    dan, Jul 23, 2003, in forum: Python
    Replies:
    8
    Views:
    391
    Terry Reedy
    Jul 23, 2003
  2. Haoyu Zhang

    confused about Python assignment

    Haoyu Zhang, Oct 31, 2003, in forum: Python
    Replies:
    5
    Views:
    469
    Michael Hudson
    Oct 31, 2003
  3. Replies:
    25
    Views:
    686
    Steve Holden
    May 18, 2006
  4. nagy
    Replies:
    36
    Views:
    998
    Terry Reedy
    Jul 20, 2006
  5. Chris
    Replies:
    34
    Views:
    1,509
Loading...

Share This Page