【随手记】python中的nonlocal关键字

简介: 【随手记】python中的nonlocal关键字

看一段代码,下边这段代码用于将二叉搜索树转换为升序排列的双向链表:

"""
# Definition for a Node.
class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
"""
class Solution:
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        if not root:
            return root
        # 递归函数,用于中序遍历和连接节点
        def recursion(root):
            nonlocal prev, head
            if root:
                # 递归遍历左子树
                recursion(root.left)
                # 将当前节点与前一个节点连接起来
                if prev:
                    prev.right = root
                    root.left = prev
                else:
                    # 当前节点是最左的节点,将其赋值给head
                    head = root
                prev = root
                # 递归遍历右子树
                recursion(root.right)
        prev = None  # 前一个节点
        head = None  # 头节点
        recursion(root)
        # 将头节点和尾节点连接起来,形成循环双向链表
        head.left = prev
        prev.right = head
        return head

去掉nonlocal,会报错:

UnboundLocalError: cannot access local variable 'prev' where it is not associated with a value

解释:

nonlocal 是Python中的关键字,用于声明一个嵌套函数中的变量是来自于其外部函数的局部作用域,而不是来自于全局作用域。

在这段代码中,prevhead 是在 recursion 函数之外定义的变量。然而,我们需要在 recursion 函数中对它们进行修改。为了在 recursion 函数中能够访问并修改这些变量,我们使用 nonlocal 关键字来声明它们。

这样,在 recursion 函数中对 prevhead 的修改将会影响到它们在 treeToDoublyList 方法中的值。这使得我们能够在 recursion 函数中正确地处理节点的连接和循环链表的生成。

再看下边一段二叉树中序遍历的代码:

class Solution:
    def inorderSearch(self, root: 'Node') -> 'Node':
        if not root:
            return None
        res = []
        def inorder(node):
            if node:
                inorder(node.left)
                res.append(node.val)
                inorder(node.right)
        
        inorder(root)
        return res

res同样是在外层函数中定义然后在内层函数中使用,为什么这里没有加上nonlocal也没有报错?

在这段代码中,res 是一个列表,它是在外层函数 treeToDoublyList 中定义的。在 Python 中,列表是可变对象,可以在函数内部通过引用进行修改。

inorder 函数中,虽然 res 是在外层函数中定义的,但是我们只是对其进行修改,没有重新赋值。因此,Python 会默认将 res 视为外层函数中定义的变量,而不是新的局部变量。

nonlocal 不同,nonlocal 用于改变外层函数的局部变量,而不是修改可变对象的值。因此,在使用 nonlocal 时,我们需要明确告诉 Python 我们要修改的是外层函数的局部变量。而对于可变对象,Python 默认会将其视为外层函数的局部变量,因此不需要使用 nonlocal

总结起来,列表等可变对象可以在函数内部进行修改,而不需要使用 nonlocal;而对于需要修改外层函数的局部变量时,我们需要使用 nonlocal 关键字。

目录
相关文章
|
20天前
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
121 2
|
1月前
|
缓存 供应链 监控
1688item_search_factory - 按关键字搜索工厂数据接口深度分析及 Python 实现
item_search_factory接口专为B2B电商供应链优化设计,支持通过关键词精准检索工厂信息,涵盖资质、产能、地理位置等核心数据,助力企业高效开发货源、分析产业集群与评估供应商。
|
1月前
|
JSON 监控 数据格式
1688 item_search_app 关键字搜索商品接口深度分析及 Python 实现
1688开放平台item_search_app接口专为移动端优化,支持关键词搜索、多维度筛选与排序,可获取商品详情及供应商信息,适用于货源采集、价格监控与竞品分析,助力采购决策。
|
1月前
|
缓存 监控 算法
唯品会item_search - 按关键字搜索 VIP 商品接口深度分析及 Python 实现
唯品会item_search接口支持通过关键词、分类、价格等条件检索商品,广泛应用于电商数据分析、竞品监控与市场调研。结合Python可实现搜索、分析、可视化及数据导出,助力精准决策。
|
1月前
|
JSON 缓存 供应链
电子元件 item_search - 按关键字搜索商品接口深度分析及 Python 实现
本文深入解析电子元件item_search接口的设计逻辑与Python实现,涵盖参数化筛选、技术指标匹配、供应链属性过滤及替代型号推荐等核心功能,助力高效精准的电子元器件搜索与采购决策。
|
1月前
|
缓存 自然语言处理 算法
item_search - Lazada 按关键字搜索商品接口深度分析及 Python 实现
Lazada的item_search接口是关键词搜索商品的核心工具,支持多语言、多站点,可获取商品价格、销量、评分等数据,适用于市场调研与竞品分析。
|
3月前
|
人工智能 JavaScript 前端开发
Python中常见的关键字
Python中常见的关键字是语言内置的特殊单词,具有特定功能,如控制逻辑、定义函数等。关键字不可作为变量名使用,否则会导致语法或类型错误。本文详细介绍了关键字的含义、分类及常见示例,并列举了常见报错原因与解决方法。
164 0
|
3月前
|
存储 人工智能 大数据
Python中的yield关键字
在Python中,`yield`关键字用于创建生成器函数,实现懒惰计算和状态保存。它能逐个生成值,节省内存,适用于处理大数据集或无限序列。通过生成器函数和表达式,可以高效地进行数据过滤与递增序列生成,提高代码效率与可维护性。
341 0
|
10月前
|
C语言 Python
[oeasy]python054_python有哪些关键字_keyword_list_列表_reserved_words
本文介绍了Python的关键字列表及其使用规则。通过回顾`hello world`示例,解释了Python中的标识符命名规则,并探讨了关键字如`if`、`for`、`in`等不能作为变量名的原因。最后,通过`import keyword`和`print(keyword.kwlist)`展示了Python的所有关键字,并总结了关键字不能用作标识符的规则。
194 9

推荐镜像

更多