如何在Python中移除两个反向链表之间的交错?

3

我在编写程序时遇到了一个问题: 我想创建两个列表,其中一个是倒序的。问题是这两个列表交织在一起,我不希望出现这种情况。 代码:

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 不会被改变。谢谢。


欢迎来到 Stack Overflow;这个问题与“机器学习”无关,请不要滥用不相关的标签(已删除)。 - desertnaut
1
“intertwined”的意思是什么? - rok
请在问题中添加所需的输出。 - RightmireM
@Derte Trdelnik的回答是正确的解决方案。 - RightmireM
4个回答

4
你想创建一个变量 a 的深拷贝。
import copy

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

当你只是复制了a的子列表时,实际上是以引用的方式复制了它们,导致a和b内部都有相同的子列表。

1
如果列表的格式已知,并且列表非常大,则“手动”创建新的子列表可能更快。 - tobias_k

1

如果列表的布局始终相同且您已知,则可以使用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

制作深拷贝:

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

0

不清楚您需要什么,请编辑原始问题让我们知道您需要什么输出。但是,这里有一些建议...

第一个问题是;您没有两个列表。您有ab,它们都是嵌套列表的嵌套列表(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
        ]
    ]

所以你需要决定你想要哪些东西被反转。

第二个问题是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)")

...aA是同一个对象,但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])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接