Pure Soul

  1. 首页
  2. 算法
  3. 正文

列表推导式和[]*N的区别

2020年10月19日 1676点热度 2人点赞 0条评论

列表推导式是常见的生成方式,同时[]*N也是快速生成多种元素的快捷方式。
例如以下两种生成方式:

a=[[0]*5]*5
b=[[0 for _ in range(5)] for _ in range(5)]

生成的初始矩阵都是5*5的0矩阵:

[
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0], 
 [0, 0, 0, 0, 0]
]

但是真正对其中的元素进行赋值之后就会发现问题:

a[0][0]=2
b[0][0]=2
# a的输出
[
[2, 0, 0, 0, 0], 
[2, 0, 0, 0, 0], 
[2, 0, 0, 0, 0], 
[2, 0, 0, 0, 0], 
[2, 0, 0, 0, 0]
]
# b的输出
[
[2, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0], 
[0, 0, 0, 0, 0]
]

可以看出[]*N的方式生成的时候其实实现的是浅拷贝,而列表推导式则是完全开辟新的空间,因此对b的元素赋值之后不会相互影响。接着再使用id()验证一下我们的想法:

a=[[0]*5]*5
a[0][0]=2
b=[[0 for _ in range(5)] for _ in range(5)]
b[0][0]=2
if a[0] is a[1]:
    print('a[0] id is ',id(a[0]))
    print('a[1] id is ', id(a[1]))
    print('a是浅拷贝')
    print('-' * 50)
else:
    print('a[0] id is ',id(a[0]))
    print('a[1] id is ', id(a[1]))
    print('a不是浅拷贝')
    print('-' * 50)

if a[0][0] is a[1][0]:
    print('a[0][0] id is ',id(a[0][0]))
    print('a[1][0] id is ', id(a[1][0]))
    print('a是浅拷贝')
    print('-' * 50)
else:
    print('a[0][0] id is ',id(a[0][0]))
    print('a[1][0] id is ', id(a[1][0]))
    print('-'*50)

if b[0] is b[1]:
    print('b[0] id is ',id(b[0]))
    print('b[1] id is ', id(b[1]))
    print('a是浅拷贝')
    print('-' * 50)
else:
    print('b[0] id is ',id(b[0]))
    print('b[1] id is ', id(b[1]))
    print('b不是浅拷贝')
    print('-' * 50)

if b[0][0] is b[1][0]:
    print('b[0][0] id is ',id(b[0][0]))
    print('b[1][0] id is ', id(b[1][0]))
    print('b是浅拷贝')
    print('-' * 50)
else:
    print('b[0][0] id is ',id(b[0][0]))
    print('b[1][0] id is ', id(b[1][0]))
    print('b不是浅拷贝')
    print('-' * 50)

输出如下:

a[0] id is  2248332523272
a[1] id is  2248332523272
a是浅拷贝
--------------------------------------------------
a[0][0] id is  140712520688048
a[1][0] id is  140712520688048
a是浅拷贝
--------------------------------------------------
b[0] id is  2248332530312
b[1] id is  2248332530056
b不是浅拷贝
--------------------------------------------------
b[0][0] id is  140712520688048
b[1][0] id is  140712520687984
b不是浅拷贝
--------------------------------------------------

由此验证了我们的想法,正因为这样的拷贝原因,因而在使用的时候最好采用列表推导式,而不是简单地[]*N的方法

标签: 暂无
最后更新:2020年12月28日

ycq

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2021 oo2ee.com. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS