3

I’m writing a program and I have a problem: I want to create two lists, one of which is reversed. The problem is that the two lists are intertwined and I don’t want that. Code:

a = [[[]], [[0.4, 2]], [[0.8, 1]]]
b = [i for i in reversed(a)]
#a = [[[]], [[0.4, 2]], [[0.8, 1]]] and b = [[[0.8, 1]], [[0.4, 2]], [[]]]
b[0][0][1] = 100
#b = [[[0.8, 100]], [[0.4, 2]], [[]]]
#a = [[[]], [[0.4, 2]], [[0.8, 100]]]

I want when I change b, a not to be changed. Thanks.

vestland
  • 55,229
  • 37
  • 187
  • 305

4 Answers4

4

you want to create a deep copy of a

import copy

a = [[[]], [[0.4, 2]], [[0.8, 1]]]
b = copy.deepcopy(list(reversed(a)))

when you just copied the sublists of a you just copied them by reference, both a and b had the same lists inside of them

Derte Trdelnik
  • 2,656
  • 1
  • 22
  • 26
  • 1
    If the format of the list is known, and the list is very large, then "manually" creating new sub-lists is probably faster. – tobias_k Oct 24 '19 at 11:47
1

While you can use deepcopy, if the layout of the list is always the same and known to you, it is probably considerably faster to "manually" copy the lists, in particular if the lists are very large.

>>> a = [[[random.random() for _ in range(random.randint(0, 10))]] for _ in range(100)]
>>> b = copy.deepcopy(list(reversed(a)))
>>> c = [list(map(list, x)) for x in reversed(a)]
>>> a[::-1] == b == c
True

>>> %timeit copy.deepcopy(list(reversed(a)))
1000 loops, best of 3: 375 µs per loop
>>> %timeit [list(map(list, x)) for x in reversed(a)]
10000 loops, best of 3: 35.5 µs per loop

(I remember the question having been tagged as "machine learning", so this might be relevant.)

tobias_k
  • 81,265
  • 12
  • 120
  • 179
0

Make a deep copy:

a = [[[]], [[0.4, 2]], [[0.8, 1]]]

from copy import deepcopy

b = [deepcopy(i) for i in reversed(a)]

So you'll get:

b[0][0][1] = 100
repr(a)              # '[[[]], [[0.4, 2]], [[0.8, 1]]]'
Edouard Thiel
  • 5,878
  • 25
  • 33
0

It's not clear what you need, so please edit the original question to let us know what output you need. But, some suggestions...

The first issue is; you don't have two lists. You have a and b, both of which are a nested list of nested lists (3 levels deep) for a total of 14 lists involved.

a = [ # First level list "a"
        [ # Second level list I.e. a[0]
            [] # Third level list a[0][0]
        ], 

        [ # Second list I.e. a[1]
            [0.4, 2] # Third level list a[1][0] = 0.4, a[1][1] = 2 
        ], 

        [ # Second level list I.e. a[2]
            [0.8, 1] # Third level list a[2][0] = 0.8, a[2][1] = 1
        ]
    ]

So you need to decide where you want things reversed.

The second issue is the idea of a reference versus a copy in Python. A good discussion starts here. But, simply put, a variable name is a reference to an object - not the object itself.

So, when you create a with ...

a = [[[]], [[0.4, 2]], [[0.8, 1]]]

...you create a list object in memory, with the variable reference a. That list object contains references to three other list objects which have been created in memory (a[0], a[1], a[3]), each one of which contains a reference to one additional list object (a[0][0], a[1][0], a[2][0]).

If you you assign a to A with ...

a = [[[]], [[0.4, 2]], [[0.8, 1]]]
print ("the memory location for object 'a' is:", hex(id(a)))

A = a
print ("the memory location for object 'A' is:", hex(id(A)), "(The same location)")

b = [i for i in reversed(a)]
print ("the memory location for object 'b' is:", hex(id(b)), "(A different location)")

... a and A are the same object, but b is a new object. So print(a is b) returns False.

I.e. ...

the memory location for object 'a' is: 0x7fdc65b12308
the memory location for object 'A' is: 0x7fdc65b12308 (The same location)
the memory location for object 'b' is: 0x7fdc65b126c8 (A different location)

HOWEVER, as pointed out by @Derte Trdelnik above, when you created b, you only copied the reference for the sublists - NOT the object. I.e.

a = [[[]], [[0.4, 2]], [[0.8, 1]]]
b = [i for i in reversed(a)]
print ("the memory location for object 'a' is:", hex(id(a)))
print ("the memory location for object 'b' is:", hex(id(b)), "(A different location)")
print ("the memory location for sub-list object 'a[1]' is:", hex(id(a[1])) )
print ("the memory location for sub-list object 'b[1]' is:", hex(id(b[1])), "(The same location as a[1])" )

OUTPUT:

the memory location for object 'a' is: 0x7f49b46f59c8
the memory location for object 'b' is: 0x7f49b46f5a08 (A different location)
the memory location for sub-list object 'a[1]' is: 0x7f49b46f5908
the memory location for sub-list object 'b[1]' is: 0x7f49b46f5908 (The same location as a[1])
RightmireM
  • 2,381
  • 2
  • 24
  • 42