首页 > 技术文章 > 关于列表元素的删除

chuangming 2018-02-22 15:36 原文

在删除列表元素时,Python 会自动对列表内存进行收缩,并移动列表元素,以保证元素之间没有空隙。每当插入或删除一个元素之后,该元素位置后面所有元素的索引就都改变了。以下代码说明这个问题。

x = [1, 2, 1, 2, 1, 1, 1]

for i in x:
    print(i)
    if i == 1:
        x.remove(i)
    print(x)

#输出结果
# 1
# [2, 1, 2, 1, 1, 1]
# 1
# [2, 2, 1, 1, 1]
# 1
# [2, 2, 1, 1]
# 1
# [2, 2, 1]

可见,由于 Python 的自动内存管理机制,通过这种方式并不能实现把 “1” 去除的效果。因此,我们下面试试切片的方法。

x = [1, 2, 1, 2, 1, 1, 1]

for i in x[::]:
    print(i)
    if i == 1:
        x.remove(i)
    print(x)

#输出结果
# 1
# [2, 1, 2, 1, 1, 1]
# 2
# [2, 1, 2, 1, 1, 1]
# 1
# [2, 2, 1, 1, 1]
# 2
# [2, 2, 1, 1, 1]
# 1
# [2, 2, 1, 1]
# 1
# [2, 2, 1]
# 1
# [2, 2]

可见,切片的方式可以实现把 “1” 去除的效果。可是,这又是为什么呢?下面我们通过以下代码来说明一下原因。

x = [1, 2, 1, 2, 1, 1, 1]
x1 = x[::]
for i in x1:
    print(x1)
    print(id(x1))
    print(i)
    if i == 1:
        x.remove(i)
    print(x)
    print(id(x))
    print()

#输出结果
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 1
# [2, 1, 2, 1, 1, 1]
# 2608486089864
# 
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 2
# [2, 1, 2, 1, 1, 1]
# 2608486089864
# 
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 1
# [2, 2, 1, 1, 1]
# 2608486089864
# 
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 2
# [2, 2, 1, 1, 1]
# 2608486089864
# 
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 1
# [2, 2, 1, 1]
# 2608486089864
# 
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 1
# [2, 2, 1]
# 2608486089864
# 
# [1, 2, 1, 2, 1, 1, 1]
# 2608486091208
# 1
# [2, 2]
# 2608486089864

由于在 for 循环中用的是同一个 x[::] ,因此我们用一个变量 x1 来接收它,然后再循环内部打印它的值和它的 id,发现它的值和 id 保持不变,也就是说,切片得到的 x[::] 在循环过程中保持不变,而且 x[::] 的 id 不同于 x 的 id,所以 x 变化并不会导致 x[::] 改变,因此可以实现去除 “1” 的效果。

 

END

推荐阅读