再踩Python的Shallow Copy

最近人工智能很火,Python也不可避免地跟着再火一把。
有天在微博上刚好看到这么一段话:

@寒冬winter:我来谈两个新标准:写出一个动态规划(最大子段和)再谈算法,写出模拟退火、遗传和神经网三大算法之一的小demo再谈AI。这不过分吧?

由于我自己也是比较注重基础的,所以挺赞同这句话的。虽然现在算法工程师经常自嘲为“调参工程师”,但那也是人家自嘲,好比写工程代码的研发工程师,也可以自嘲为“搬砖工程师”。但说实话,真把这种话当真的,估计砖没搬好还反倒添乱。

于是我就在想,不如重拾生疏已久的Python手艺,先来刷刷DP题练练手,再去深入看看人工智能领域。

回头看了下我之前写的Python博文,已经是很多年以前了,当时从2.7切换到3还是遇到了些问题,没想到这么多年过去了,Python2.7的份额还是那么大,不由得我感慨了下

不过这么多年过去了,除了隐约的PVM记忆和记录下来的博文,Python 2.7和Python 3对我来说都一样,想想还是从Python 3.5写起吧。

回到题目来。
在刷题过程中要用Python来构造二维数组,虽然我脑子里第一飘过的是不等长的数组,如:

[
[1]
[2, 3]
[4, 5, 6]
]

毕竟Python和Objective-C一样,万物皆对象,[]中放的都是PyObject,无所谓长短。

但是后续由于写C语言的惯性,我写起代码来还是预先初始化了N*N的数组来:routes = [[0] * n] * n,相比于长度不一致的数组元素来说,比较可以避免越界操作。

结果在做写操作的时候遇到了问题:

routes = [[0] * n] * n
routes[0][0] = 1
print(routes)
输出了:[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

第一反应还是有点懵的,因为按照C语言的逻辑,每一个元素都位于不同的地址才对,怎么一行赋值语句写了三个不同地址?

直到后来看到Shallow Copy这两个单词,我脑子里面瞬间回忆起多年以前刚写Python的时候,也踩过这个坑。

想来这是Python这种解释型脚本语言在因为引入了类似PVM这种虚拟机带来的性能变慢(相较于C语言之类的),而尽力去追求的优化。

如果要预先初始化出Deep Copy的二维数组,可以这么写:routes = [([-1] * n) for i in range(n)],不过参考Python这种优化态度,可能在需要时再append不等长的数组元素会比较好?也就是说,会比较pythonic

猜你喜欢

转载自blog.csdn.net/jasonblog/article/details/54729101