1

I have defined a Color class as below. Since I need to store multiple colors and their respective node ID (which has the color), I made a list colors to store them. However, every time a node color is changed, I do not want to update list colors directly (another function will decide whether to update or not), so I need to store a copy of colors to *tmp_colors* before calling the decision func, and update colors with *tmp_colors* if result is Yes.

I managed to make a copy of new list *tmp_colors*, but *tmp_colors[0]* is still pointing to colors[0] , resulting in the update of both list.

  1. How can I make a copy of class object in colors[0] to *tmp_colors[0]*?
  2. If I were to update colors[0] later on, what's the best way?
  3. Is there any better design instead of the example below (define class, and list of class object)?

class Color:
    __elems__ = "num", "nodelist",

    def __init__(self):
        self.num = 0
        self.num_bad_edge = 0

    def items(self):
        return [
                (field_name, getattr(self, field_name)) 
                 for field_name in self.__elems__]

def funcA():

    nodeCount = 2
    colors = []
    for i in range(0, nodeCount):
        colors.append(Color())

    colors[0].num = 2
    colors[0].nodelist = [10,20]
    colors[1].num = 3
    colors[1].nodelist = [23,33, 43]

    print "colors"
    for i in range(0, nodeCount):
        print colors[i].items()

    tmp_colors = list(colors)
    print "addr of colors:" 
    print id(colors)
    print "addr of tmp_colors:" 
    print id(tmp_colors)    
    print "addr of colors[0]:" 
    print id(colors[0])
    print "addr of tmp_colors[0]:" 
    print id(tmp_colors[0])

    tmp_colors[0].num = 2
    tmp_colors[0].nodelist = [10,21]

    print "\ntmp_colors"
    for i in range(0, nodeCount):
        print tmp_colors[i].items()

    print "\ncolors <<< have been changed"
    for i in range(0, nodeCount):
        print colors[i].items()

Result:

colors
[('num', 2), ('nodelist', [10, 20])]
[('num', 3), ('nodelist', [23, 33, 43])]
addr of colors:
32480840
addr of tmp_colors:
31921032
addr of colors[0]:
32582728
addr of tmp_colors[0]:
32582728                           <<<<<< --- expecting a new addr

tmp_colors
[('num', 2), ('nodelist', [10, 21])]
[('num', 3), ('nodelist', [23, 33, 43])]

colors <<< have been changed
[('num', 2), ('nodelist', [10, 21])]   <<<<<< --- expecting no change [10, 20]
[('num', 3), ('nodelist', [23, 33, 43])]

2 Answers 2

5

You copied the list, but not the contents, which you then change. Your Color instances are mutable too, and tmp_colors[0] refers to the same instance as colors[0] does. Sure, tmp_colors is a copy, but the Color instance is not.

Use copy.deepcopy() to recursively create copies of your objects:

from copy import deepcopy

tmp_colors = deepcopy(colors)
1

You can use the copy module

import copy
tmp_colors = copy.deepcopy(colors)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.