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

不懂就问, Python 中递归对 List 进行 append 的一个问题

  •  
  •   royrs · 2022-01-23 21:41:05 +08:00 · 1367 次点击
    这是一个创建于 1065 天前的主题,其中的信息可能已经有所发展或是发生改变。

    代码如下:

    def QuanPaiLie(n):
        if n < l:
            for i in range(l):
                if plList[i] == 0:
                    plList[i] = numsList[n]
                    QuanPaiLie(n + 1)
                    plList[i] = 0
        else:
            qplList.append(plList)
    
    if __name__ == '__main__':
        numsList = [1, 2, 3]
        l = len(numsList)
        qplList = []
        plList = [0 for i in range(l)]
        
        QuanPaiLie(0)
        print(qplList)
    

    运行后输出的结果是:

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

    而如果将qplList.append(plList)改为qplList.append(str(plList)),却可以输出:

    ['[1, 2, 3]', '[1, 3, 2]', '[2, 1, 3]', '[3, 1, 2]', '[2, 3, 1]', '[3, 2, 1]']
    

    且不论算法的优劣,仅这个现象该如何解释呢。

    请大佬赐教。

    6 条回复    2022-01-24 12:15:04 +08:00
    kidlj
        1
    kidlj  
       2022-01-23 21:55:34 +08:00   ❤️ 1
    没细看,应该是 Python 二维列表常见的一个错误用法,看一下我之前写的这篇文章是否对得上。


    https://github.com/kidlj/site/blob/9aab72decaf58618dcd726110c0a30de6fb7f92b/_posts/2014-11-25-python-init.mkd
    rabbbit
        2
    rabbbit  
       2022-01-23 21:56:34 +08:00   ❤️ 1
    qplList.append(plList) 改成 qplList.append(plList[:])

    为什么的话搜: python 可变 不可变对象
    ipwx
        3
    ipwx  
       2022-01-23 22:28:58 +08:00   ❤️ 1
    。。因为列表是引用。

    你无数次添加了同一个列表进去
    Nitroethane
        4
    Nitroethane  
       2022-01-23 22:48:29 +08:00   ❤️ 1
    list 对象的 append 方法是 append 一个对象到列表中。因为 plList 是 list 对象,所以 append 进去是 [0,0,0] 这种。str() 是内建函数,作用是:当传递给 str() 函数的对象有 __str__() 方法时调用 __str__() 方法,否则调用 repr() 函数。https://docs.python.org/3/library/stdtypes.html#str
    silentsee
        5
    silentsee  
       2022-01-24 11:32:54 +08:00   ❤️ 1
    print(qplList)是在所有递归都结束的时候,而 append(plList)中 plList 是引用,递归结束时已经被你置为 0 了,而 append(str(plList))中的 str(plList)是在递归最深处求值的,即使到了递归结束,因为 str 是不可变对象,所以 print 出了求值时候的值
    royrs
        6
    royrs  
    OP
       2022-01-24 12:15:04 +08:00
    感谢大家的回复,我慢慢看看。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3851 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 05:11 · PVG 13:11 · LAX 21:11 · JFK 00:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.