• python疑难问题---5、二维列表初始化


    python疑难问题---5、二维列表初始化

    一、总结

    一句话总结:

    可以用c = [[0]*4 for _ in range(3)]的方式来初始化3行4列的二维数组,用乘号(*)重复不可变数据类型(这里是int 0),用循环重复可变数据类型(这里是列表)

    1、b = [[0] * 4] * 3 初始化3行4列 二维数组不可行的实质?

    列表在用乘号(*)重复的时候,重复的列表的地址是一样的,而python中的列表是可变数据类型,地址一样,代表指向的是同一个列表,当然会一变全变,也就是b[0][0]变的时候,b[1][0]和b[2][0]都会跟着变

    二、二维列表初始化

    博客对应课程的视频位置:5、二维列表初始化
    https://www.fanrenyi.com/video/32/306

    一、分析

    当我们使用python处理数据的时候,经常会遇到需要初始化一个二维列表,然后对列表的每一个子项目(我们这里假设也是列表)进行操作。

    列表的乘号(*)操作可以重复元素,比如

    In [16]:
    print(['Hi!'] * 4)
    
    ['Hi!', 'Hi!', 'Hi!', 'Hi!']
    

    所以我们考虑用 *号 来初始化列表

    In [17]:
    a = [0] * 5
    print(a)
    
    [0, 0, 0, 0, 0]
    
    In [18]:
    print(id(a[0]))
    print(id(a[1]))
    print(id(a[2]))
    print(id(a[3]))
    print(id(a[4]))
    
    140724000563568
    140724000563568
    140724000563568
    140724000563568
    140724000563568
    
    In [19]:
    a[1]=1
    a[3]=7
    print(a)
    
    [0, 1, 0, 7, 0]
    
    In [20]:
    print(id(a[0]))
    print(id(a[1]))
    print(id(a[2]))
    print(id(a[3]))
    print(id(a[4]))
    
    140724000563568
    140724000563600
    140724000563568
    140724000563792
    140724000563568
    

    普通初始化的列表

    In [21]:
    aa = [0,0,0,0,0]
    print(id(aa[0]))
    print(id(aa[1]))
    print(id(aa[2]))
    print(id(aa[3]))
    print(id(aa[4]))
    
    140724000563568
    140724000563568
    140724000563568
    140724000563568
    140724000563568
    
    In [22]:
    aa[1] = 11
    aa[2] = 22
    print(aa)
    
    [0, 11, 22, 0, 0]
    
    In [23]:
    print(id(aa[0]))
    print(id(aa[1]))
    print(id(aa[2]))
    print(id(aa[3]))
    print(id(aa[4]))
    
    140724000563568
    140724000563920
    140724000564272
    140724000563568
    140724000563568
    

    我们可以根据这种思路快速初始化二维列表

    二、有坑的方式

    In [24]:
    b = [[0] * 4] * 3
    print(b)
    
    [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
    

    这样的确非常快的初始化了一个列表,但是这样有一个很大的问题

    In [25]:
    b[0][0] = "这个方法不行"
    print(b)
    
    [['这个方法不行', 0, 0, 0], ['这个方法不行', 0, 0, 0], ['这个方法不行', 0, 0, 0]]
    

    我们可以看到,我们本来是希望将 "这个方法不行" 赋值给b[0][0],结果发现b[i][0]的值都是 "这个方法不行" 了

    为什么会这样呢?

    我们来看这个式子:b = [[0] 4] 3中的后面这个3,将前面的列表重复了3次,我们重复之后,得到的子列表的地址是一样,

    而python中列表是可变数据类型(也就是列表里面数据变的时候,地址不会变,值相同的两个列表,地址也是不一样的,如果两个列表地址是一样的,代表的是同一个列表),既然代表的是同样一个列表,那么一个变,其它跟着变,也很好解释了

    b = [[0] 4] 3 初始化3行4列 二维数组不可行的实质

    列表在用乘号(*)重复的时候,重复的列表的地址是一样的,而python中的列表是可变数据类型,地址一样,代表指向的是同一个列表,当然会一变全变,也就是b[0][0]变的时候,b[1][0]和b[2][0]都会跟着变 </font>

    In [26]:
    print(id(b[0]))
    print(id(b[1]))
    print(id(b[2]))
    
    1728181289928
    1728181289928
    1728181289928
    

    我们来看一下正常方式初始化的列表

    我们来看一下正常方式初始化的列表,对应的二维列表中的一维列表的地址肯定是不一样的,地址不一样,操作肯定互不影响

    In [27]:
    bb = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
    print(id(bb[0]))
    print(id(bb[1]))
    print(id(bb[2]))
    
    1728183167816
    1728183168136
    1728183168008
    
    In [28]:
    bb[0][0] = 1
    bb[2][2] = 5
    print(bb)
    
    [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 5, 0]]
    

    三、正确的方式

    可以用c = [[0] * 4 for _ in range(3)]的方式来初始化3行4列的二维数组,用乘号(*)重复不可变数据类型(这里是int 0),用循环重复可变数据类型(这里是列表)

    In [31]:
    c = [[0] * 4 for _ in range(3)]
    c[0][0]='这个方法行'
    print(c)
    
    [['这个方法行', 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
    
    In [32]:
    print(id(c[0]))
    print(id(c[1]))
    print(id(c[2]))
    
    1728183168200
    1728183189704
    1728183189640
    
    In [ ]:
     
     
  • 相关阅读:
    Python NLP入门教程
    一个月入门Python爬虫,轻松爬取大规模数据
    Python爬虫实战案例:爬取爱奇艺VIP视频
    探索Python F-strings是如何工作
    Ruby 和 Python 分析器是如何工作的?
    超级干货,python常用函数大总结
    Python 开发者的 6 个必备库,你都了解吗?
    神经网络中 BP 算法的原理与 Python 实现源码解析
    新手程序员必学的代码编程技巧
    零基础小白怎么用Python做表格?
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/13222638.html
Copyright © 2020-2023  润新知