python中序列使用的小坑

开发中,我们时常会使用序列操作:

l = [1,2,3]
l * 2
>>>[17]: [1, 2, 3, 1, 2, 3]

5*'abc'
>>>'abcabcabcabcabc'

python中 + 和 * 都有这个规律,不修改原有的操作对象,而是构建一个全新的序列

我们现在来看两个例子:
一个包含三个列表的列表

board = [['_'] * 3 for i in range(3)]
board
>>>[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]

board[1][2] = 'x'
>>>[['_', '_', '_'], ['_', '_', 'x'], ['_', '_', '_']]

这里我们看到我们成功的修改了预期值,我们再看下一个例子
用更简单的建立序列的方法

weird_board = [['_'] * 3] * 3

这样建立是不是比上面的例子要简单的多,但是这个序列有一个问题,就是这个序列里面的的三个对象的指针都是指向同一个地方,

In [33]: for i in [['_'] * 3] * 3:
    ...:     print(id(i))

4446930504
4446930504
4446930504

看到三个对象的内存地址是一致的,那我们再来看看上一个列子里面的对象地址

In [34]: for i in [['_'] * 3 for i in range(3)]:
    ...:     print(id(i))
    ...:
4447022600
4446945352
4446421896

可以清楚的看到三个地址是不一致的,
这就说明了一个问题:for 循环是连续添加新对象进入列表

现在我们来修改下其中的一个值

In [39]: weird_board[1][2] = 'x'

In [40]: weird_board
Out[40]: [['_', '_', 'x'], ['_', '_', 'x'], ['_', '_', 'x']]

问题出现了,我们只是修改了一个位置的值,但是三个对象全变了,
这个问题的实质还是这就是对象列表里面的一个小坑,希望大家在开发的时候注意这点。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,107评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,011评论 25 709
  • 岁月是一首磨人的歌,黯然的,带走了青春年华,只剩下千疮百孔的面容。 刘先生 夜晚的街道继承着白日的喧嚣,灯光,...
    hero_5ff9阅读 353评论 0 1