【python笔记】列表操作append(list)与append(list[:])的区别;列表的就地修改与非就地修改

问题背景:

当有一个数组list1 = [1,2,3],需要根据list1创建一个二维数组list2时,

想到了列表的list2.append(list1)

结果由于list1.pop()更改,list2的结果也随之变化,开始摸不着头脑。

append(list)与append(list[:])的区别

append(list)

执行list2.append(list1)时,实际上是将list1列表的引用添加到了list2中。

意味着,list2列表中的元素与list1列表指向同一个对象;

因此,在对list1进行就地修改操作修改list1时,修改便反馈在list2上。

当然,如果对list1进行的是非就地修改操作,list2结果并不会受到影响。

list1 = [1, 2, 3]  
list2 = []  
# 添加list1的引用  
list2.append(list1)  
# 现在,list2和list1 都指向同一个列表  
print(list2)  # 输出: [[1, 2, 3]]    
# 修改list1 
list1.append(4)  
# list2中的元素也被修改了,因为它们指向同一个列表  
print(list2)  # 输出: [[1, 2, 3, 4]]  

append(list[:])

执行list2.append(list1[:])时,实际上创建了一个list1列表的浅拷贝,并将这个浅拷贝的引用添加到list2中。

意味着,list2中的元素是一个新列表,与list1在内存中占有不同的位置;

因此,无论对list1进行何种操作,均不会影响list2。

# 添加list1的浅副本  
list2.append(list1[:])  
# 现在,res和path指向不同的列表  
print(list2)  # 输出: [[1, 2, 3]]  
# 修改list1
list1.append(4)  
# list2中的元素没有改变,因为它们是独立的列表  
print(list2)  # 输出: [[1, 2, 3]]

就地修改与非就地修改的区别

刚才有提到就地修改和非就地修改的说法,到底何为列表的就地修改?何为非就地修改呢?

非就地修改(Non-in-place Modification)

创建原始数据的一个新副本,并在该副本上进行修改,而原始数据保持不变。

常见操作:

1、切片复制新变量

original = [1, 2, 3]  
modified = original[:]  # 浅拷贝  
modified.append(4)  # 修改新列表,原始列表不变

2、列表推导式

original = [1, 2, 3, 4, 5]  
modified = [x * 2 for x in original]  # 创建新列表,每个元素都是原始元素的两倍

3、map()filter()函数

original = [1, 2, 3, 4, 5]  
modified = list(map(lambda x: x * 2, original))  # 每个元素乘以2
print(modified)     # 输出:[2, 4, 6, 8, 10]

filtered_iter = filter(lambda x: x > 3, original)
# filter()返回的是一个迭代器,因此我们需要将它转换成列表或其他数据结构来查看结果  
filtered_list = list(filtered_iter) 
print(filtered_list)  # 输出: [4, 5]

4、列表的+操作符

list1 = [1, 2, 3]  
list2 = [4, 5, 6]  
combined = list1 + list2  # 合并成新列表

就地修改(In-place Modification)

直接修改原始数据,不会创建新的数据副本。

常见操作:

1、append()、pop()、remove()、insert()、sort()、reverse()等直接修改列表本身的方法

2、切片赋值

list1 = [1, 2, 3, 4, 5]  
list1[1:3] = [20, 30]  # 直接替换列表中的一部分

3、__setitem__特殊方法

这不是日常编程中常用的方法,但它是Python中所有可变序列类型(如列表)支持的就地修改机制的一部分。

my_list = [1, 2, 3]  
my_list.__setitem__(1, 10)  # 直接设置索引为1的元素为10

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值