关于Python地址存储的一点思考

本文通过解决LeetCode上的全排列问题,深入探讨了Python中列表作为参数传递时的引用特性。作者分享了一个常见陷阱及其解决方案,并对比了Python与Java在此方面的差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天刷题刷到LeetCode上的46题:46. 全排列

很自然的写出了如下代码

class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        def f(num, cur, res):
            if len(cur) == len(nums):
                #print cur
                res.append(cur)
                return
            for i in range(len(nums)):
                if nums[i] in cur:
                    continue
                else:
                    cur.append(nums[i])
                    f(nums, cur, res)
                    cur.pop()
        res = []
        f(nums, [],res)
        return res

结果却是 全为空 如[ [],[],[],]???

出于对自己的自信, 我偷看了别的java代码, 确认是思路没毛病的。。

可问题出在哪呢?

仔细查阅java 和Python的 函数传递规则 也没发现问题

突然灵机一动!!!

我添加了一笔 f(nums, cur[:], res), 成功跑通, 解释如下, 

                    # 这里为什么传一个新的引用 cur[:] ?
                    # 因为 后边cur.pop 相当于每次把之前的值删除, res中的cur也会随之删除, 因为传递的是地址。 所以res的结果也会变!!!
                    #  这是java 中 与Python的不同 , res的元素和cur仍然是一个地址空间!!

简单来说: 就是res = [cur], cur = [] , 这种结构的存储, res 中的 元素和cur 指向 同一个地址空间。  所以 不是随便改变cur的,  应该了解到 res的结果也会改变, 如果不想让他改变, 那么应该重新传递一个新的值(新的地址空间),Python为了省内存,  可谓无所不用其极!!!

其实 append这个函数可以这样理解, 它 不生成新的东西, 只是做了结构上的整理!

https://www.cnblogs.com/geaozhang/p/7111961.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值