python assignment

Discussion in 'Python' started by dan, Jul 23, 2003.

  1. dan

    dan Guest

    without stirring the pot too much --

    could someone please point me to whatever documentation exists on the
    philosophy, semantics, and practical implications of how Python
    implements the assignment operator? So far I can't find much useful
    in the regular documentation. I understand the basic concept that
    names are bound to objects which exist on the heap, but that still
    doesn't explain why a = b doesn't _always_ cause a to point to the
    same object as b. What determines when the object in question is
    copied? What determines when a future maniplulation of the variable
    will cause it to point to an object that is already referenced by
    another variable? (see code below for an example).

    What I need is an exact and unambiguous algorithm for determining when
    an assignment will change the id of the variable (or should I say,
    when the evaluation of an expression will cause a new object to be
    created). Some of the issues involved can be discerned from the
    following session:

    >>> a = 1
    >>> b = a
    >>> a is b

    True
    >>> a += 1
    >>> a -= 1
    >>> a is b

    True
    >>> a = 1.0
    >>> b = a
    >>> a is b

    True
    >>> a += 1
    >>> a -= 1
    >>> a is b

    False
    >>> a == b

    True
    dan, Jul 23, 2003
    #1
    1. Advertising

  2. dan

    dan Guest

    Ok, thanks for the responses. I think I 'get' it now. However I do
    think it would be an excellent idea to have a bit of exposition on
    this subject in the Python tutorial, or perhaps in a separate section.
    It's not really hard to understand once you realize what's going on,
    but I suspect it causes no end of confusion for both new programmers
    and old (those used to langs such as C++).

    Here's a better example of how a newbie can get confused:

    >>> a = (1,2) #a is a tuple
    >>> b = a #b & a now point to same object on heap
    >>> a += (3,) #tuples are immutable so += returns a new one
    >>> b == a #b points to old, a points to new

    False
    >>> a = [1,2] #a is a list
    >>> b = a #a & b point to same object again
    >>> a += [3] #a is mutable, so += mutates it
    >>> b == a #of course

    True
    >>> a = a + [4] #hmm... one *might* think this is eqiv. to a += [4]
    >>> a == b

    False #but NOOO!!
    >>> a

    [1, 2, 3, 4]
    >>> b

    [1, 2, 3]

    Now that I understand what's happening, it makes sense, but initially
    this sort of behavior was quite mysterious.

    -dbm

    (dan) wrote in message news:<>...
    > without stirring the pot too much --
    >
    > could someone please point me to whatever documentation exists on the
    > philosophy, semantics, and practical implications of how Python
    > implements the assignment operator? So far I can't find much useful
    > in the regular documentation. I understand the basic concept that
    > names are bound to objects which exist on the heap, but that still
    > doesn't explain why a = b doesn't _always_ cause a to point to the
    > same object as b. What determines when the object in question is
    > copied? What determines when a future maniplulation of the variable
    > will cause it to point to an object that is already referenced by
    > another variable? (see code below for an example).
    >
    > What I need is an exact and unambiguous algorithm for determining when
    > an assignment will change the id of the variable (or should I say,
    > when the evaluation of an expression will cause a new object to be
    > created). Some of the issues involved can be discerned from the
    > following session:
    >
    > >>> a = 1
    > >>> b = a
    > >>> a is b

    > True
    > >>> a += 1
    > >>> a -= 1
    > >>> a is b

    > True
    > >>> a = 1.0
    > >>> b = a
    > >>> a is b

    > True
    > >>> a += 1
    > >>> a -= 1
    > >>> a is b

    > False
    > >>> a == b

    > True
    dan, Jul 23, 2003
    #2
    1. Advertising

  3. dan

    Juha Autero Guest

    "Tim Peters" <> writes:

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


    I'm confused. I thought that the idea of __iadd__ is that for
    *mutable* types it modifies existing object instead of returning new
    one. So, was that a typo or are Python lists just bad desing:


    >>> l=[]
    >>> f=l
    >>> f+=[1]
    >>> f

    [1]
    >>> l

    [1]

    --
    Juha Autero
    http://www.iki.fi/jautero/
    Eschew obscurity!
    Juha Autero, Jul 23, 2003
    #3
  4. In article <>, Ben Finney wrote:

    >> What I need is an exact and unambiguous algorithm for determining when
    >> an assignment will change the id of the variable

    >
    > As I understand it, this is specific to the implementation of each type.
    > The only sensible way to code is as if the identity of an object, on
    > assignment, were completely unpredictable.
    >
    > The examples you gave showed that integers share identity with other
    > integers of the same value, while floats do not.


    I believe that's only true for small integers, isn't it?

    --
    Grant Edwards grante Yow! I want to TAKE IT
    at HOME and DRESS IT UP in
    visi.com HOT PANTS!!
    Grant Edwards, Jul 23, 2003
    #4
  5. dan

    Peter Hansen Guest

    Grant Edwards wrote:
    >
    > In article <>, Ben Finney wrote:
    >
    > >> What I need is an exact and unambiguous algorithm for determining when
    > >> an assignment will change the id of the variable

    > >
    > > As I understand it, this is specific to the implementation of each type.
    > > The only sensible way to code is as if the identity of an object, on
    > > assignment, were completely unpredictable.
    > >
    > > The examples you gave showed that integers share identity with other
    > > integers of the same value, while floats do not.

    >
    > I believe that's only true for small integers, isn't it?


    Google finds "LOADI - a fast load instruction for small positive integers
    (those referenced by the small_ints array in intobject.c)" and checking
    that file is left as an exercise to the reader. I'm going to blindly
    assume this is directly related to the issue in question... ;-)

    -Peter
    Peter Hansen, Jul 23, 2003
    #5

  6. >> > The examples you gave showed that integers share identity with other
    >> > integers of the same value, while floats do not.


    >> I believe that's only true for small integers, isn't it?


    Peter> Google finds "LOADI - a fast load instruction for small positive
    Peter> integers (those referenced by the small_ints array in
    Peter> intobject.c)"

    LOADI was an instruction I implemented a few years ago when investigating
    bytecode optimization. It was never added to the Python virtual machine
    (ceval.c).

    Skip
    Skip Montanaro, Jul 23, 2003
    #6
  7. Shallow vs Deep copies [was Re: python assignment]

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    On Tue, 22 Jul 2003 22:46:56 -0400,
    Tim Peters <> wrote:

    > The rule that the object in question is never copied. There are no
    > exceptions to this. Copying an object requires invoking some method
    > of the object, or applying some function to the object. For example,
    > d.copy() returns a (shallow) copy of a dict d, and L[:] returns a
    > (shallow) copy of a list L.



    To clarify for me please.

    A shallow copy of an object, returns an object that contains references
    to objects within the copied object, yes?

    so a list consisting of [1,2,a,"a"] when copied shallowly, will return
    exactly that, but when copied deeply, will reture [1,2,"whatever a
    points to","a"] yes?

    If I understand the above correctly.... how deep does a deep copy go?
    can you vary the depth? Or is it binary, shallow or deep?

    Thanks.

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.2.2 (GNU/Linux)

    iD8DBQE/Hr9Bd90bcYOAWPYRAnaYAKDDRFGR6FG3ytgN2dwf7w1shDND3QCgs33B
    8jNxKhsF1Ti7bkbPzbCxEx4=
    =6a1K
    -----END PGP SIGNATURE-----

    --
    Jim Richardson http://www.eskimo.com/~warlock

    Linux, because eventually, you grow up enough to be trusted with a fork()
    Jim Richardson, Jul 23, 2003
    #7
  8. Re: Shallow vs Deep copies [was Re: python assignment]

    Jim Richardson wrote:

    > A shallow copy of an object, returns an object that contains
    > references
    > to objects within the copied object, yes?
    >
    > so a list consisting of [1,2,a,"a"] when copied shallowly, will return
    > exactly that, but when copied deeply, will reture [1,2,"whatever a
    > points to","a"] yes?


    No, that's what the first list already consists of:

    >>> a = "whatever a points to"
    >>> l1 = [1, 2, a, "a"]
    >>> l1

    [1, 2, 'whatever a points to', 'a']

    A shallow copy makes a new object of the object passed in, and maintains
    the same reference. A deep copy makes a new object, _and_ a new object
    of all references it contains, and on down the line.

    The difference between shallow and deep copying is not apparent when
    you're talking about immutable objects, since immutable objects need not
    ever be literally copied. Consider a simpler case of a list containing
    a single element, which is an instance of a custom class:

    >>> class C: pass

    ....
    >>> c = C()
    >>> x = [c]
    >>> y = copy.copy(x)
    >>> x is y

    0
    >>> x[0] is y[0]

    1
    >>> z = copy.deepcopy(x)
    >>> x is z

    0
    >>> x[0] is z[0]

    0
    >>> x[0]

    <__main__.C instance at 0x810ba8c>
    >>> z[0]

    <__main__.C instance at 0x814c9fc>

    Shallow copying makes a duplicate of the parent object. Deep copying
    makes a duplicate of everything.

    --
    Erik Max Francis && && http://www.alcyone.com/max/
    __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
    / \ Of war men ask the outcome, not the cause.
    \__/ Seneca
    Erik Max Francis, Jul 23, 2003
    #8
  9. dan

    Terry Reedy Guest

    Re: Shallow vs Deep copies [was Re: python assignment]

    "Erik Max Francis" <> wrote in message
    news:...

    > immutable objects need not ever be literally copied


    > Shallow copying makes a duplicate of the parent object. Deep

    copying
    > makes a duplicate of everything.


    To be more exact, because first statement is true,
    second_statement.replace('everything', 'all mutables'),
    which is to say, 'as much as needed'.

    >>> import copy
    >>> l1=[(),[]]
    >>> l2=copy.deepcopy(l1)
    >>> for i in l1+l2: print id(i)

    ....
    7669904
    8422784
    7669904 #same ()
    8428448 #different []

    Terry J. Reedy
    Terry Reedy, Jul 23, 2003
    #9
    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. Tim Peters

    RE: python assignment

    Tim Peters, Jul 23, 2003, in forum: Python
    Replies:
    5
    Views:
    320
    Terry Reedy
    Jul 25, 2003
  2. Haoyu Zhang

    confused about Python assignment

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

Share This Page