V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
northisland
V2EX  ›  问与答

OMG,记录我掉进的一个 Python 的巨简单的坑,并求教怎么爬出来?

  •  1
     
  •   northisland · 2017-10-24 11:26:09 +08:00 · 2055 次点击
    这是一个创建于 2595 天前的主题,其中的信息可能已经有所发展或是发生改变。
    In[]: a = [[0, 0]]*3
    In[]: a
    Out[]: [[0, 0],
            [0, 0],
            [0, 0]]
    In[]: a[1][1]=3
    In[]: a
    Out[]: [[0, 3],
            [0, 3],
            [0, 3]]
    

    我只想改[1, 1]的元素,我该怎么改这个代码呢? 列表这个东东,至今我没有吃透。。。

    我能想到的是,这种数组来生成

    a = numpy.zeros(shape=(10, 3), dtype=int).tolist()
    

    提前谢过各位的指教和观看

    7 条回复    2017-10-24 15:02:16 +08:00
    zfz
        1
    zfz  
       2017-10-24 11:58:04 +08:00   ❤️ 1
    In [1]: a = [[0, 0] for i in range(3)]

    In [2]: a
    Out[2]: [[0, 0], [0, 0], [0, 0]]

    In [3]: a[1][1] = 3

    In [4]: a
    Out[4]: [[0, 0], [0, 3], [0, 0]]

    In [5]: id(a)
    Out[5]: 4490425912

    In [6]: id(a[0])
    Out[6]: 4486759560

    In [7]: id(a[1])
    Out[7]: 4490542472 #与 a[0]地址不同

    In [8]: b = [[0, 0]] * 3

    In [9]: id(b[0])
    Out[9]: 4490539808

    In [10]: id(b[1])
    Out[10]: 4490539808 # 与 b[0]相同


    这个情况有趣,以前也没发现。不用*,用列表生成式可以满足。应该是用*生成列表的时候,引用了相同的对象,所以你改动这个对象,导致整个列表都变。这个估计要看 CPython 具体实现。
    coderluan
        2
    coderluan  
       2017-10-24 12:00:14 +08:00   ❤️ 1
    coderluan
        3
    coderluan  
       2017-10-24 12:03:09 +08:00   ❤️ 2
    简单来说 *3 是浅拷贝,创建二维数组请用 in range
    gamexg
        4
    gamexg  
       2017-10-24 12:10:13 +08:00   ❤️ 1
    列表是引用,那三个实际使指向同一对象。
    这样 for 下可以复制列表。

    a[i]=a[i][:]
    或者
    a[i]=[v for v in a[i]]
    jedihy
        5
    jedihy  
       2017-10-24 14:29:52 +08:00 via iPhone
    慎用*号开辟数组,原因上面已经说了,浅拷贝。
    xiadd
        6
    xiadd  
       2017-10-24 14:39:34 +08:00
    就是引用类型 指向同一个地址, 改变其中一个,三个都会发生变化
    scusjs
        7
    scusjs  
       2017-10-24 15:02:16 +08:00
    哈哈遥想起本科刚刚学 Python 时候被这个坑哭,原因上面讲了,浅拷贝。
    可以这么做:
    a = [[0, 0] for i in range(3)]
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2577 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 05:22 · PVG 13:22 · LAX 21:22 · JFK 00:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.