Python3 列表能被闭包函数使用,整数变量却不行呢?

2022-04-20 18:44:30 +08:00
 DuDuDu0o0

问题:

最近在使用 python3 刷题,发现一个比较奇怪的现象,想用闭包的特性去使用一个外层作用域的变量,如果这个变量是 list 的话,则 ok ,非 list 就会报错,我需要怎么做才可以闭包使用整数变量呢

如下面 ide 截图这样: https://imgtu.com/i/LsNiB8

代码如下:

class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        pre = -sys.maxsize -1
        o = []
        def trace(root) -> bool:
            if not root:
                return True
            if not trace(root.left): return False
            o.append(root.val) # 为什么 list 可以被闭包进来
            if pre >= root.val: # 但是整数变量却不行呢?
                return False
            else:
                pre = root.val
            if not trace(root.right):return False
            return True

        return trace(root)



1483 次点击
所在节点    程序员
6 条回复
eurekavip
2022-04-20 18:52:04 +08:00
python 里面赋值会自动变成局部变量,你的 else 里面有赋值操作:pre = root.val
DuDuDu0o0
2022-04-20 18:55:42 +08:00
@eurekavip 感谢,我把 pre = root.val 注释之后确实没报错了,
有什么办法能在 闭包里 对外面的变量赋值呢?难道只能 read ?
pursuer
2022-04-20 18:58:43 +08:00
使用 nonlocal 引入外部变量
LeeReamond
2022-04-20 22:23:02 +08:00
这是语言特性,具体问题就是子 block 对父 block 中资源的处理方案,各个语言对这三点的处理不尽相同,一般的三个问题是 1 、能否感知,2 、能否读取,3 、能否修改。

就 python 来说是能感知和读取,修改的话会创建副本,所以父 block 不用担心变量被子 block 或调用乱改。可能有一些考量在,虽然目前我个人来说更喜欢闭包可以全权修改的方案。

解决方案一般是 nonlocal 或者传递指针,传递指针是指传进子 block 的是对象或者[0,],子 block 中用 item.property += 1 或者 item[0] += 1 的方式修改。nonlocal 效率更高,不过传指针更灵活一些,性能其实倒是不太有所谓,python 列表单次寻址耗时大概是 20 纳秒左右,在绝大多数场景中这并不是值得在意的开销。
stimw
2022-04-21 01:11:41 +08:00
我的 c++只用来刷题。。🐶
cheng6563
2022-04-21 09:13:41 +08:00
你套个 list 就行了,只有一个变量的 list 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/848218

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX