Как убрать сложность между двумя обращенными списками в Python? - PullRequest
3 голосов
/ 24 октября 2019

Я пишу программу, и у меня проблема: я хочу создать два списка, один из которых перевернут. Проблема в том, что два списка переплетены, и я не хочу этого. Код:

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]]]

Я хочу, чтобы при изменении b, a не менялся. Спасибо.

Ответы [ 4 ]

4 голосов
/ 24 октября 2019

вы хотите создать глубокую копию a

import copy

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

, когда вы только что скопировали подсписки a, вы просто скопировали их по ссылке, и a, и b имели одинаковые списки внутри них

1 голос
/ 24 октября 2019

Хотя вы можете использовать deepcopy, если компоновка списка всегда одинакова и вам известна, вероятно, значительно быстрее «вручную» копировать списки, особенно если списки очень велики.

>>> 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

(я помню вопрос, помеченный как «машинное обучение», так что это может быть актуально.)

0 голосов
/ 24 октября 2019

Непонятно, что вам нужно, поэтому, пожалуйста, отредактируйте исходный вопрос, чтобы сообщить нам, какой вывод вам нужен. Но некоторые предложения ...

Первый вопрос;у вас нет двух списков. У вас есть a и b, каждый из которых представляет собой вложенный список вложенных списков (глубиной 3 уровня), что в общей сложности включает 14 списков.

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
        ]
    ]

Так что вам нужно решить, где вы хотите, чтобы все было наоборот.

Второй вопрос - идея reference против copy в Python. Хорошее обсуждение начинается здесь . Но, проще говоря, имя переменной - это ссылка на объект, а не сам объект.

Итак, когда вы создаете a с ...

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

... вы создаете объект списка в памяти со ссылкой на переменную a. Этот объект списка содержит ссылки на три других объекта списка, которые были созданы в памяти (a[0], a[1], a[3]), каждый из которых содержит ссылку на один дополнительный объект списка (a[0][0], a[1][0], a[2][0]).

Если вы назначите a на A с помощью ...

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 и A - это один и тот же объект, но b это новый объект. Так что print(a is b) возвращает False.

Т.е. ...

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)

ОДНАКО, как указано @Derte Trdelnik выше, когда вы создали b, вы скопировали только ссылку для подсписков, а НЕ объект. Т.е.

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])" )

ВЫХОД:

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])
0 голосов
/ 24 октября 2019

Сделайте глубокую копию:

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

from copy import deepcopy

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

Так вы получите:

b[0][0][1] = 100
repr(a)              # '[[[]], [[0.4, 2]], [[0.8, 1]]]'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...