python的二维数组生成问题

背景:

笔者最近在做一个数据统计程序时,需要用到二维数组。为了一行搞定生成同值二维数组,结果遇到了一些小bug,实验了下,终于找到了问题并修复。

前言:

如何简单快速生成 连续10个k的字符串,很简单

'k'*10
#kkkkkkkkkk

那如何快速生成 连续十个True的数组(列表)呢?别再for .... xxx.append()了,不美观也多了好几行代码。一行搞定即可。

[True]*10
#[True, True, True, True, True, True, True, True, True, True]

那如果生成 2x3的全是0的二维数组呢?

按照上面的套路还不简单?也是一行搞定(笔者也是这么想的,结果bug了。嘛,先看下结果吧,确实是想要的)手到擒来嘛。

[[0]*3]*2
#[[0, 0, 0], [0, 0, 0]]

其实这样有bug!其实这样有bug!其实这样有bug!

案例:

用新旧两种方法生成全是0的2x3数组,修改坐标(1,1)的值为9.

l1 = [[0]*3]*2
l2 = [
    [0,0,0],
    [0,0,0],
]
print('l1原',l1)
print('l2原',l2)
l1[1][1] = 9
l2[1][1] = 9
print('l1改',l1)
print('l2改',l2)

#结果:
#l1原 [[0, 0, 0], [0, 0, 0]]
#l2原 [[0, 0, 0], [0, 0, 0]]
#l1改 [[0, 9, 0], [0, 9, 0]]
#l2改 [[0, 0, 0], [0, 9, 0]]

土方法正常的改值了。我们帅气的方法(伪)出现bug了。你会发现所有第二列的数值都改成了9。

为什么呢?

这是因为python的机制问题。

在python里,int float str都是深拷贝的,即'x'*n,'x'的值会被复制成n份;

但是list,dist和其他class等,都是浅拷贝的,即仅仅把对象的内存地址拷贝了一份,所有拷贝出来的数据都会共用一组数据。即c里我们常说的指针。

[[0]*3]*2

里的[0]*3确实进行了深拷贝,于是就相当于变成了 [[0 ,0 ,0 ] ]*2。而外层拷贝变成了拷贝list,即浅拷贝,也就是无论拷贝多少行都在使用同一行的数据。

改变1行数据就变成了改变所有行数据。

 

因此,正确的写法是(当然也是 一行 哦)

l3 = [([0] * 3) for i in range(2)]
print('l3原',l3)
l3[1][1] = 9
print('l3改',l3)

#结果
#l3原 [[0, 0, 0], [0, 0, 0]]
#l3改 [[0, 0, 0], [0, 9, 0]]

是不是帅气而简单呢?

网上还有其他引用其他库的方法去处理。但笔者认为,import最少的库,最高效率,最少代码 去完成是最酷的。至少新手看起来 通俗易懂高大上。

转载于:https://my.oschina.net/jacky326/blog/3028659

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值