糯米

TI DaVinci, gstreamer, ffmpeg
随笔 - 167, 文章 - 0, 评论 - 47, 引用 - 0
数据加载中……

python中最容易让人火大的两个问题

1. list对象的*操作符
>>> a = [[1]]*10
>>> a
[[
1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]
>>> a[1][0] = 2
>>> a
[[
2], [2], [2], [2], [2], [2], [2], [2], [2], [2]]
>>>
也就是说,这10个对象实际上是指向的同一个list对象。
这是bug,还是feature?或者是优化?
总之是蛮让人火大的就是了。
用 a = [[0] for x in range(10)] 这种写法就没有这个问题了。


2. 深拷贝
>>> a = [[0] for x in range(10)]
>>> a
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> b = list(a)
>>> b
[[0], [0], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> a[1][0] = 2
>>> b
[[0], [
2], [0], [0], [0], [0], [0], [0], [0], [0]]
>>> 
b = list(a)
意味着a和b中都存放这10个指针。指向[0], [0], [0] .... 这10个对象。
a[1][0] = 2 后 a 自己的值没有改变,改变的是第二个 [0] 对象。
由于 b 也是指向它的,所以打印b的时候会发现这一点。
这个问题是自己经常犯的问题,大多都是debug半天才知道怎么回事。
使用
import copy
b = copy.deepcopy(a)
可以解决这个问题。

3. 如何避免这些问题
要时刻记得,python中的对象就只有两种,mutable和immutable。也就是可改变和不可改变。
immutable的包括:str  tuple  int ...
mutable可改变的包括:list dict ...
immutable的就是原子的。mutable里面存放的都是指向mutable或者immutable的指针。
调试的时候,可以使用id(obj)获得每个对象的id。这个貌似就是python管理的运行时的对象的地址。
如果发现两个obj的id相同,那他们就是同一个货。。

posted on 2011-02-08 15:38 糯米 阅读(406) 评论(0)  编辑 收藏 引用 所属分类: Python


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理