今天遥感课正好学到卷积运算,然后又布置了作业。可是手工一个个算(敲计算器)太累了,于是我就在下一节计算机课上争取偷懒→_→比较顺利的是,懒是偷成了。但是写的程序有个小bug——就是会改变原始的输!入!数!据!
作为一个强迫症,输入数据肯定要有备份的嘛!于是便开始查找原因:一开始认为是类的问题,后来发现问题并不这么简单——

如图,self.table是原始输入数据,res是暂存的结果。先是把self.table复制一份给res.table,然后对res.table进行处理。嗯,一切都很正常!然后一运行……卧槽?self.table怎么也全变成4了?这不对啊!我不是copy了嘛!对了,一定是我copy用得不对,于是我在idle下进行了如下测试:
>>> lst=[1,2]
>>> a=lst.copy()
>>> a[0]=999
>>> a
[999, 2]
>>> lst
[1, 2]
很正常啊!这不是对的嘛?后来通过和同学的讨论,发现了这么一个神奇的现象:
>> >lst=[1,2]
>>> a=lst.copy()
>>> a[0]=999
>>> a
[999, 2]
>>> lst
[1, 2]
>>> lst=[1,2]
>>> a=lst.copy()
>>> lst is a
False
>>> lst[0] is a[0]
True
>>> a[0]=999
>>> lst[0] is a[0]
False
哇!原来copy后的列表确实和原列表不是一个东西,但是列表中对应的元素还是一个东西。但是由于整数不可被更改,所以当a[0]=999时,python会新开辟一个内存存999这个值,所以内存地址又不一样了。
回到最开始的程序中,由于被copy的列表时一个嵌套列表,即列表里的元素还是列表。而列表是可修改的,所以导致尽管看上去列表被copy了一个副本,里面的元素还是保持着关联性。所以,改了res.table[x][y]就相当于改了self.table[x][y]。
那么这个问题怎么解决呢?很简单,其实通过copy模块的copy.deepcopy方法就行了。如下图所示:

最后的最后,其实我很久以前(也没多久)在哪里看到过copy和deepcopy函数这个东西,也曾经理解过这些内容,但是因为记性不好= =今天又忘掉了,所以在自己的博客中水一篇这样的文章,提醒自己,也能为后来疑惑者解惑吧~




Warning: A non-numeric value encountered in /www/wwwroot/i.pegasi.top/wp-content/themes/begin/inc/function/comment-template.php on line 31
2020年04月03日 04:32 -49楼
Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in /www/wwwroot/i.pegasi.top/wp-content/themes/begin/inc/function/setting.php on line 1367