2024-06-16 18:43:19 发布
网友
我很困惑为什么这个从列表中删除特定对的短片段失败了:
g = [[7, 11], [7, 8], [3, 10], [3, 8], [8, 9], [11, 10], [11, 2], [11, 9]] u = 3 g_cpy = g for e in g_cpy: if u == e[0]: g.remove(e) print g
它不会删除条目[3,8],但会删除[3,10]。我错过了什么?你知道吗
g_cpy = g
不创建列表的副本,只创建对同一对象的引用,然后在迭代过程中修改该对象。另一个问题是重复的remove调用在时间复杂度方面是不好的(每个调用都是O(N))。最好使用理解来从头开始构建新列表(总体线性复杂度)。您仍然可以使用该技术和通过使用切片分配来改变原始列表:
remove
O(N)
g[:] = [e for e in g if u != e[0]]
我认为[3, 8]没有被删除的原因是
[3, 8]
您删除了数组中的第3个元素,e将是g_cpy中的第4个元素。你知道吗
g_cpy
您已经删除了g_cpy中的[3, 10],因此g_cpy的第4个元素将是[8, 9]而不是[3, 8],这就是[3, 8]没有被删除的原因。你知道吗
[3, 10]
[8, 9]
如果像g_cpy = g那样复制列表,它只会复制内存地址。所以它们都指向同一个物体。如果删除g中的项目,g_cpy中的项目也将被删除。你知道吗
g
如果您想避免这个问题,可以复制类似g_cpy = g[::]的列表。它将条目对象复制到其他内存,而不仅仅是复制内存地址。你知道吗
g_cpy = g[::]
不创建列表的副本,只创建对同一对象的引用,然后在迭代过程中修改该对象。另一个问题是重复的
remove
调用在时间复杂度方面是不好的(每个调用都是O(N)
)。最好使用理解来从头开始构建新列表(总体线性复杂度)。您仍然可以使用该技术和通过使用切片分配来改变原始列表:我认为
[3, 8]
没有被删除的原因是您删除了数组中的第3个元素,e将是
g_cpy
中的第4个元素。你知道吗您已经删除了
g_cpy
中的[3, 10]
,因此g_cpy
的第4个元素将是[8, 9]
而不是[3, 8]
,这就是[3, 8]
没有被删除的原因。你知道吗如果像
g_cpy = g
那样复制列表,它只会复制内存地址。所以它们都指向同一个物体。如果删除g
中的项目,g_cpy
中的项目也将被删除。你知道吗如果您想避免这个问题,可以复制类似
g_cpy = g[::]
的列表。它将条目对象复制到其他内存,而不仅仅是复制内存地址。你知道吗相关问题 更多 >
编程相关推荐