问题场景:
在处理leetcode的回溯算法问题时,使用**append()**函数对列表进行追加,发现列表中追加的内容为空,但之只要list()或tuple()之后,列表可正常追加数据
在回溯算法的场景中对列表追加列表,追加的列表为空的现象
问题描述
在回溯算法中需要将每次的结果追加到组合中,但使用Python的append追加会出现追加的是空列表的现象,但是用list()或tuple()追加,则会追加成功
### 找出1-9中组合和为k所有组合,一个数字只能出现一次,不能重复。返回所有的组合
def backtrack(idx,k,combination):
if k==0:
combinations.append(combination) ## 追加的列表为空列表
combinations.append(list(combination)) ## 使用该方法可以追加成功
else:
for i in range(idx,10):
if i<=k:
combination.append(i)
backtrack(i+1,k-i,combination)
combination.pop() ## 追加的列表为空是这里的原因
原因分析:
这是因为`append()’函数添加列表时,是添加列表的“引用地址”而不是添加列表内容,当被添加的列表发生变化时,添加后的列表也会同步发生变化。
例如:append()
添加列表时,添加的是列表引用地址。即传入的是combination的地址,但combination的数据是需要一直pop()
出去的。所以才会出现传入的列表一直为空列表的原因。
d = [1,2,3]
print(id(d)) ## 1907872981632
print(id(list(d))) ## 1907870406912
说明list(d) 和 列表d 不是同一个地址,list(d)这个地址是一个对该列表的深拷贝,列表d 的改变不会对其造成影响。
解决方案:
目前通过使用 list() 强制转换,将值复制到另一个地址,防止列表中数据变化造成后续的结果出现错误
需要了解Python中的可变数据和不可变数据类型:
参考连接:https://blog.csdn.net/tqh267/article/details/116539797
已知Python有六种数据类型:
- Number(数字)
- String(字符串)
- List(列表)
- Tuple(元组)
- Set(集合)
- Dictionary(字典)
其中,这六种数据类型又分为 可变数据类型 和 不可变数据类型。
可变数据类型:List、Set、Dictionary
不可变数据类型: Number、String、Tuple
数据类型是如何定义的可变数据和不可变数据?
当数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变,对于这种数据类型,称为不可变数据类型。
当数据类型的对应变量的值发生了改变,那么它对应的内存地址不会发生改变,对于这种数据类型,称为可变数据类型。
## 测试list
l = [0,1,2,3,4]
l[2] = 9 ## 可以完成数据修改,则为可变数据类型
## 测试tuple
tpl = (0,1,2,3)
tpl[2] = 9 ## 程序会报错误,'tuple' object does not support item assignment 表示元组类型不支持修改,这就表明tuple为不可变数据类型
Python中常见的 List 和 Str的数据类型转换:
combination_l = [‘1’,‘2’,‘3’,‘4’,‘5’]
combination_s = “12345”
- List->Str:
s = ’‘.join(combination_l) ### s = '12345',注意只有当list中的元素为 str 时,才能进行该转换
- Str->List:
l = list(combination_s) ### l = [1,2,3,4,5]