2

As I am trying to make a copy of a list and do some stuff with the copy of the list. Somehow my original list is modified as well. I already looked at different memory allocatinos and different ways of assigning the lists. So far no luck... Any ideas?

    row = 0
    column = 0
    table1 = copy.copy(table[:])

    temptable = []
    temptable = table[:]

    print id(table)
    print table
    print id(table1)
    print table1
    print id(temptable)
    print temptable

    for i in temptable:
        for j in i:
            if type(j) == str:
                temptable[row][column] = 0
            column = column + 1
        column = 0
        row = row + 1
    result=[]   

    for column in zip(*temptable):
        try:
                result.append(sum(map(int,column)))
            except ValueError:
                result.append(0)


    print table
    print table1
    print temptable

/#### Results

163783148
[[0, 'ZZZ', 'XXX', 'YYY', 'AAA', 0, 0], ['BBB', 1, 1, 0, 26, 28, 0], ['CCC', 26, 0, 0, 0, 26, 0], ['DDD', 0, 26, 0, 0, 26, 0], ['EEE', 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]

163669036
[[0, 'ZZZ', 'XXX', 'YYY', 'AAA', 0, 0], ['BBB', 1, 1, 0, 26, 28, 0], ['CCC', 26, 0, 0, 0, 26, 0], ['DDD', 0, 26, 0, 0, 26, 0], ['EEE', 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]

163783468
[[0, 'ZZZ', 'XXX', 'YYY', 'AAA', 0, 0], ['BBB', 1, 1, 0, 26, 28, 0], ['CCC', 26, 0, 0, 0, 26, 0], ['DDD', 0, 26, 0, 0, 26, 0], ['EEE', 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]

[[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 26, 28, 0], [0, 26, 0, 0, 0, 26, 0], [0, 0, 26, 0, 0, 26, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]

[[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 26, 28, 0], [0, 26, 0, 0, 0, 26, 0], [0, 0, 26, 0, 0, 26, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]

[[0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 0, 26, 28, 0], [0, 26, 0, 0, 0, 26, 0], [0, 0, 26, 0, 0, 26, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0]]
Roman Bodnarchuk
  • 29,461
  • 12
  • 59
  • 75
Jasper
  • 628
  • 1
  • 9
  • 19

4 Answers4

12

Your original list contains inner lists:

[[0, 'ZZZ', 'XXX', 'YYY', 'AAA', 0, 0], 
 ['BBB', 1, 1, 0, 26, 28, 0], ...
]

The inner list are actually stored as references, i.e.:

[ location-of-list-0, 
  location-of-list-1, ...
]

When you copied the list, you actually copied a list of references to the same lists stored in your original list. This is called shallow copy, as it copies references rather than contents.

Use deep copy to create a totally separate list.

Illustrations

Original List

enter image description here

Shallow copy

enter image description here

Deep copy

enter image description here

Community
  • 1
  • 1
Adam Matan
  • 128,757
  • 147
  • 397
  • 562
4

You need deepcopy to also copy the objects in the list, and not only the references.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
2

You should also copy inner lists, so deepcopy may help you.

Roman Bodnarchuk
  • 29,461
  • 12
  • 59
  • 75
0

As [:] does only create a copy-slice of the list the slice is actually applied to, the reference to the objects stay the same. Using deepcopy does recursively copy every item that can be pointed out.

class Foo:

    def __init__(self):
        self.name   = "unknown"

    def __repr__(self):
        return "Foo: " + self.name

    def __copy__(self):
        f = Foo()
        f.name = self.name
        return f

    def __deepcopy__(self, d):
        return self.__copy__()

lst = [Foo()]
lst[0].name = "My first foo"

lst2 = lst[:]
lst2.append(Foo())
lst2[1].name = "My second foo"

print lst
print lst2

output

[Foo: My first foo]
[Foo: My first foo, Foo: My second foo]

lst2[0].name = "I changed the first foo"

print lst
print lst2

output

[Foo: I changed the first foo]
[Foo: I changed the first foo, Foo: My second foo]

from copy import deepcopy
lst[0].name = "My first foo"
lst3 = deepcopy(lst)
lst3[0].name = "I changed the first foo again !"

print lst
print lst3

output

[Foo: I changed the first foo]
[Foo: I changed the first foo again !]

Lists, tuples, etc do support __copy__ and __deepcopy__ method.

Niklas R
  • 16,299
  • 28
  • 108
  • 203