Syntax: pointers versus value

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Danny Castonguay

    Syntax: pointers versus value

    Simple question but I can't find the answer. Using an example:

    listA = [1 ,2]
    listB = listA
    listB.append(3)
    #listA now is [1,2,3]

    I want to avoid listA's value to change. Clearly, "listB = listA"
    creates the problem. listB and listA become two pointers to the same
    object. How then, do I duplicate the two objects; ie make a copy of the
    object that listA is pointing to and have listB point to that object.

    I'm new to python and I love it.

    Thank you,

  • Tino Lange

    #2
    Re: Syntax: pointers versus value

    On Wed, 30 Jul 2003 12:46:43 -0400, Danny Castonguay
    <castong@mathst at.concordia.ca > wrote:

    Hi!
    [color=blue]
    > Clearly, "listB = listA"
    >creates the problem. listB and listA become two pointers to the same
    >object.[/color]

    Exactly.
    [color=blue]
    > How then, do I duplicate the two objects; ie make a copy of the
    > object that listA is pointing to and have listB point to that object.[/color]

    Use:
    listB = listA[:]

    Cheers,

    Tino

    Comment

    • Danny Castonguay

      #3
      Re: Syntax: pointers versus value

      Tino Lange wrote:[color=blue]
      > Use:
      > listB = listA[:][/color]

      --------------------------------------------------------------------
      In the example I have given, it does solve the problem. However, for
      some reason I don't understand, it doesn't work in the next example:

      def ps_of_missing_e dges(initial_gr aph, missing_edges):
      num_m_e = len(missing_edg es) #number of missing_edges
      num_e_pset = 2**num_m_e
      graphs = []
      for i in range(0,num_e_p set): #iteration will stop at 2^num-1
      temp_i = i #use temp_i to find i's bit values
      new_graph = initial_graph[:]
      print 'initial_graph is ' + str(initial_gra ph)
      for j in range (0,num_m_e):
      if temp_i%2 == 1:
      new_graph[missing_edges[j][0]-1].append(missing _edges[j][1])
      temp_i = temp_i >> 1
      graphs.append(n ew_graph)
      return graphs

      --------------------------------------------------------------

      the output when I call:
      ps_of_missing_e dges([[2,3],[1],[1]], [[2,3],[3, 2]])
      is:
      initial_graph is [[2, 3], [1], [1]]
      initial_graph is [[2, 3], [1], [1]]
      initial_graph is [[2, 3], [1, 3], [1]]
      initial_graph is [[2, 3], [1, 3], [1, 2]]

      --------------------------------------------------------------
      Therefore, somehow initial_graph's value changes even though the
      assignment is new_graph = initial_graph[:]

      Assuming that the assignment does it's job, then I don't see how
      initial_graph's value changes.


      Thank you,

      Comment

      • Tino Lange

        #4
        Re: Syntax: pointers versus value

        On Wed, 30 Jul 2003 13:46:29 -0400, Danny Castonguay
        <castong@mathst at.concordia.ca > wrote:
        [color=blue]
        >new_graph = initial_graph[:]
        > initial_graph is [[2, 3], [1], [1]]
        > initial_graph is [[2, 3], [1], [1]]
        > initial_graph is [[2, 3], [1, 3], [1]]
        > initial_graph is [[2, 3], [1, 3], [1, 2]][/color]

        Hi!

        Now you have lists in lists. This is another situation.

        new_graph = initial_graph[:] will really make a copy of the outer list
        - but this outer list contains no values but once again pointers to
        other objects.

        Use the copy-module for nested copy things like that:


        Cheers,

        Tino

        Comment

        • John J. Lee

          #5
          Re: Syntax: pointers versus value

          Danny Castonguay <castong@mathst at.concordia.ca > writes:
          [color=blue]
          > Simple question but I can't find the answer. Using an example:[/color]
          [...][color=blue]
          > object. How then, do I duplicate the two objects; ie make a copy of
          > the object that listA is pointing to and have listB point to that
          > object.[/color]
          [...]




          John

          Comment

          • John Hunter

            #6
            Re: Syntax: pointers versus value

            >>>>> "Danny" == Danny Castonguay <castong@mathst at.concordia.ca > writes:

            Danny> I want to avoid listA's value to change.

            There are several ways

            listB = listA[:]

            listB = [x for x in listA]

            import copy
            listB = copy.copy(listA )
            listB = copy.deepcopy(l istA)

            These don't all do the same thing, but all satisfy the example you
            posted, eg
            [color=blue][color=green][color=darkred]
            >>> listA = [1 ,2]
            >>> listB = listA[:]
            >>> listB.append(3)
            >>> listA[/color][/color][/color]
            [1, 2]

            So far so good, but consider this case
            [color=blue][color=green][color=darkred]
            >>> listA = [[],1]
            >>> listB = listA[:]
            >>> listB[0].append(12) # changing the list at listB[0]
            >>> listB[/color][/color][/color]
            [[12], 1][color=blue][color=green][color=darkred]
            >>> listA[/color][/color][/color]
            [[12], 1]

            Sneaky, eh? So the 'listB = listA[:]' made a copy of the list, but
            not of the elements of the list. This is a shallow copy, and you
            should get the same behavior from copy.copy.

            Note that this is related to mutable and immutable objects in python.
            In the example above, I didn't replace the first item of the list, I
            changed it. Since both listA and listB contained the same object as
            their first element, changing one changes the other. If I had
            replaced that object in listB, nothing would have happened to listA
            [color=blue][color=green][color=darkred]
            >>> listA = [[],1]
            >>> listB = listA[:]
            >>> listB[0] = 12 # replacing the object, not changing it
            >>> listB[/color][/color][/color]
            [12, 1][color=blue][color=green][color=darkred]
            >>> listA[/color][/color][/color]
            [[], 1]


            If you want to avoid this, use deepcopy.
            [color=blue][color=green][color=darkred]
            >>> import copy
            >>> listA = [[],1]
            >>> listB = copy.deepcopy(l istA)
            >>> listB[0].append(12)
            >>> listB[/color][/color][/color]
            [[12], 1][color=blue][color=green][color=darkred]
            >>> listA[/color][/color][/color]
            [[], 1]

            The behavior of mutable objects bites everyone a few times when they
            begin learning python, so welcome to the club!

            John Hunter

            Comment

            Working...