python中 list 修改 再次反思 .
最近读书的时候,一些感悟,记录一下. 之前有写过有关列表中修改值的注意事项, 暂且把这个叫做 python 列表总结二
可以参考一下这个:
python修改列表问题总结
1 来看一个例子
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
l = list(range(10))
for num in l:
num *= 2
print(l)
result:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
这里列表元素没有发生改变.
2 来看下一个例子
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
""" @author: Frank @contact: frank.chang@shoufuyou.com @file: 33.py @time: 2018/9/14 下午7:41 """
if __name__ == '__main__':
l = [['a'], ['b'], ['c'], ['d']]
for number in l:
number*=2
print(l)
result:
[['a', 'a'], ['b', 'b'], ['c', 'c'], ['d', 'd']]
可以看出列表元素的值发生了改变.
同样的代码 为啥一个 元素值发生了改变,而一个没有呢?
参考 流畅的Python 8.4 节
Python 里面 是 函数参数作为引用的时候,
Python 支持的 参数传递模式 是 共享传参数 ,
共享传参数的各个形式参数 获得实参中各个 引用的副本. 也就是说 , 函数内部 的形参是实参的别名.
这种的结果是什么呢?
函数可能 修改 作为参数的可变的对象 ,却没有办法修改那些对象上的标识. (即不能把一个对象 替换成另外一个对象)简单来说,如果是可变对象可以直接修改对象的值 ,如果是不可变对象是没有办法直接在原来的对象进行 修改的.
下面的例子可以说明这一点..
在解释其环境里面实验一下
person_tuple = tuple(['name','frank'])
hobby_tuple =tuple(['swimming'])
person_tuple = tuple(['name','frank'])
hobby_tuple =tuple(['swimming'])
person_tuple
('name', 'frank')
hobby_tuple
('swimming',)
id(person_tuple),id(hobby_tuple)
(4458632456, 4458598864)
person_tuple+hobby_tuple
('name', 'frank', 'swimming')
person_tuple
('name', 'frank')
person_tuple+=hobby_tuple
person_tuple
('name', 'frank', 'swimming')
id(person_tuple)
4458568872
Python 中 元祖是不可变对象, 所以 在进行 += 的时候,Python 并没有报错,而是直接申请另一个空间来重新存 修改后的值.
可以看出 4458632456 ,和 4458568872 是不一样的. 所以python 解释其会计算值,之后赋给这个 person_tuple 对象,原来的person_tuple 会被释放掉了.
这就是元祖的不可变性,就是没有办法在原来的tuple 添加元素.
3 在看一个流畅的Python书中的一个例子
在解释器环境下面:
def add(x,y):
x += y
return x
x ,y =10,20
add(x,y)
30
x
10
y
20
x=[1,2]
y=['frank','chang']
add(x,y)
[1, 2, 'frank', 'chang']
x
[1, 2, 'frank', 'chang']
同样是 x,y 但是如果 x,y 是不可变类型, x+=y 并不会改变 x 的值.
如果 x,y 是可变类型, x+=y就会 修改x 的值.
4 总结
对于用for 迭代 可迭代对象的时候,列表中是否可以修改元素取决于,列表的元素是不是可变的对象, 如果是就可以修改.
<center>分享快乐,留住感动.2018-09-14 23:01:55 –frank
</center>