函数,作用域,树,简介

函数嵌套

在一个函数中定义了另一个函数
函数有可见范围,这就是 作用域 概念
内部函数不能在外部直接使用,会抛NameError异常,因为它不可见


作用域

一个标识符的可见范围,这就是标识符的作用域。一般常说的是变量的作用域
全局作用域
在整个程序运行环境中都可见
局部作用域
在函数、类等内部可见
局部变量使用范围不能超过其所在局部作用域

全局变量global

x = 5
def foo():
    global x
    x += 1
使用global关键字变量,将foo内的x声明为使用外部的全局作用域中定义的x
全局作用域中必须有x的定义
内部作用域使用x = 5 之类的赋值语句会重新定义局部作用域使用的变量x,但是一旦这个作用域中使用global声明x为全局的,那么x= 5相当于在全局作用域的变量x 赋值

nonlocal

使用了nonlocal关键字,将变量标记为不在本地作用域定义,而在上级的某一级局部作用域中定义,但不能是全局作用域中定义
内部函数使用nonlocal 关键字声明变量在上级作用域而非本地作用域中定义

闭包

自由变量:未在本地作用域中定义的变量
闭包: 就是一个概念,出现在嵌套函数中,指的是内层函数引用到了外层函数的自由变量,就形成了闭包。

变量名解析原则LEGB

local  本地作用域、局部作用域的local命名空间。函数调用时创建,调用结束时消亡
Enclosing,Python2.2时引入了嵌套函数,实现了闭包,这个就是嵌套函数的外部函数命名空间
Global,全局作用域,即一个模块的命名空间,函数被import时创建,解释器退出时消亡
Build-in  内建模块的命名空间,生命周期从python解释器启动时创建到解释器退出时消亡。

递归

自己调用自己

匿名函数 Python 借助Lambda表达式构建匿名函数

格式:
    lambda 参数列表 :表达式
    参数列表不需要小括号
    冒号是用来分割参数列表和表达式的
    不需要用return,表达式的值,就是匿名函数返回值
    lambda表达式(匿名函数)只能写在一行上,被称为单行函数

生成器

生成器generator
    生成器是指生成器对象,可以由生成器表达式得到,也可以使用yield关键字得到一个生成器函数,调用这个函数得到一个生成器对象
生成器函数
    函数体中包含yield语句的函数,返回生成器对象
    生成器对象,是一个可迭代对象,是一个迭代器
    生成器对象,是延迟计算、惰性求值的
    包含yield语句的生成器函数生成 生成器对象的时候,生成器函数体不会立即执行
    next(generator)会从函数的当前位置向后执行到之后碰到的第一个yield 语句,会弹出值,并暂停函数执行
    再次执行next函数,和上一条一样的处理过程
    没有多余的yield语句能被执行,继续调用next函数,会抛出StopIteration异常

普通定义
    非线性结构,每个元素可以有多个前驱和后继
    树是n(n>=0) 个元素的集合
    n= 0 时,为空树
    树只有一个特殊的没有前驱的元素,称为树的根Root
    树中除了根节点外,其余只能有一个前驱,可以有零个或多个后继
递归定义
    树T是n(n>=0)个元素的集合。n=0时,称为空树
    有且只有一个特殊元素根,剩余元素都可以被划分为m个互补相交的集合T1、T2、...T  m,每一个集合都是树,称为T的树Subtree
    子树也有自己的根

概念
    结点 :树中的数据元素
    结点的度degree:结点拥有子树的数目称为度,记作d(v)
    叶子结点:结点的度为0,称为叶子结点leaf、终端结点、末端节点
    分支结点:结点的度不为0,称为非终端结点或分支结点
    分支:结点之间的关系
    内部结点:除去根和叶子结点外的分支结点
    树的度是树内各结点的度的最大值
    结点的层次(Level):根结点为第一次层,根的孩子为第二层,以此类推,记作L(v)
    树的深度(高度):树的层次的最大值
    有序树:结点是子树是有顺序的,不能交换
    无序树:结点的子树是无顺序的,可以交换
    路径:树中的k个结点n1,n2...nk,满足ni是n(i+1)的双亲,成为n1到nk的一条路径。就是一条线串下来的,前一个都是后一个的前驱结点
    路径长度 = 路径上的节点数-1,也就是分支数
    森林:m(m>=0)棵不相交的树 集合
        对于结点而言,其子树的集合就是森林。

树的特点
    唯一的根
    子树不相交
    除了根以外,每个元素都只能有一个前驱,可以有零个或多个后继
    根结点没有双亲结点(前驱),叶子结点没有孩子结点(后继)
    双亲结点比孩子结点的层次小1

二叉树
    每个结点最多有两个子树
    二叉树不存在度数大于2 的结点
    它是有序树,左子树,右子树是有顺序的,不能交换顺序
    即使某个结点只有一颗子树,也要确定它是左子树还是右子树
    二叉树的五种基本形态
    空二叉树
    只有一个根结点
    根节点只有左子树
    根节点只有右子树
    根结点有左子树和右子树
斜树
    左斜树,所有的结点都只有左子树
    右斜树,所有的结点都只有右子树
满二叉树
    一个二叉树的所有分支结点都存在左子树和右子树,并且所有的叶子结点都只存在在最下面一层
    同样深度二叉树中,满二叉树结点最多
    k 为深度(1<=n),则结点总数为2^k-1
    完全二叉树Complete Binary Tree
    若二叉树的深度为k,二叉树的层数从1到k-1层的结点数都达到了最大个数,在第k层的结点都集中在最左边,这就是完全二叉树
    完全二叉树由满二叉树引出
    满二叉树一定是完全二叉树,但完全二叉树不一定是满二叉树
    k为深度(1<=k<=n),则结点总数最大值为2^k-1,当达到最大值的时候就是满二叉树
二叉树性质
    高度为k的二叉树,至少有K个结点
    含有n(n>=1)的结点的二叉树高度至多为n。最小为math.ceil(log2(n+1)),不小于对数值的最小整数,向上取整
    具有n个结点的完全二叉树的深度为int(log2n)+1或者math.ceil(log2(n+1))

原文地址:http://blog.51cto.com/13886193/2164259

时间: 2024-10-09 08:53:17

函数,作用域,树,简介的相关文章

我的读书笔记一函数作用域

函数作用域与全局作用域: var a=123; function f(){ alert(a); var a=1; alert(a); } f(); 很多人(包括我)都会觉得根据作用域来说函数内部可以访问局部变量和全局变量,运行结果应该是第一次弹出123,第二次弹出1;这是错误的. 运行的结果:第一次弹出undefined,第二次弹出1:这是因为上面的代码等价于: var a=123;function f(){ var a; //变量提升声明 alert(a); a=1; alert(a); }

javascript中函数作用域之”提升“

javascript中函数作用域之变量提升 当我们在函数内部用关键字var声明一个变量的时候,此变量的作用域限制在当前函数. 提升:在一个作用域内部,不管一个变量用var声明的位置在哪里,这个变量属于当前整个作用域,并且在当前作用域的任何位置都可以访问它.在javascript中,这种行为/现象称之为"提升",即一个变量在一个作用域的任何位置用var声明,javascript引擎都会把这些用var声明的变量"移动"到当前作用域的开始处. 谈到javascript这种

JavaScript 函数作用域的“提升”现象

在JavaScript当中,定义变量通过var操作符+变量名.但是不加 var 操作符,直接赋值也是可以的.例如 : message = "hello JavaScript ! " 即定义了一个全局变量message,并赋值 "Hello JavaScript!"--<JavaScript高级程序第三版> 如同往日一般,一群人在所谓的技术交流群里面相互斗图着.突然老王莫名的正经起来,在群里发了一道JavaScript的题目,让大家猜一猜这道题的答案. v

《你不知道的javascript》一、函数作用域和块作用域

函数中的作用域 所谓函数作用域,就是属于这个函数的全部变量都可以在整个函数的范围内使用及复用. 1 function foo(a) { 2 var b=a; 3 function bar(c){ 4 var c=b*2; 5 console.log(c); 6 } 7 bar(); //4 8 } 9 foo(3); 1 function foo(a) { 2 var b=a; 3 function bar(c){ 4 var c=b*2; 5 console.log(c); 6 } 7 bar

javascript篇-----函数作用域,函数作用域链和声明提前

在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的(也就是我们不能在代码段外直接访问代码段内声明的变量),我们称之为块级作用域,然而,不同于这类型的编程语言,javascript是没有块级作用域.取而代之的,javascript使用的是块级作用域:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. 在如下的所示的代码中,在不同位置定义了变量 i . j 和 k ,它们都在同一个作用域内——这三个变量在函数体内均是有定义

变量作用域&amp;函数作用域

一. 变量作用域 1)全局变量 在全局环境下声明的变量被视为全局变量. 在没有使用var进行声明的时候,变量就被定义为全局变量.在ES5的严格模式下,如果变量没有使用var来声明是会报错的. 2)局部变量 在函数体内部声明的变量被视为局部变量.其中涉及到js中的函数作用域问题. 二. 函数作用域 因为js中是没有块级作用域的概念,所谓的块级作用域就是指花括号内的的每一段代码都有其自己的作用域,但js中并不是,例如for循环中定义的变量,外界也可以访问:但是js中有函数作用域的概念,即在每一个函数

javascript的函数作用域及声明提前

废话不说:先来段代码: var scope='global';function test(){    alert(scope);        // 输出undefine:而不是global    var scope='local';      alert(scope);        // 输出local}test(); 脑算下:你可能会认为第一alert会输出global: 但是事实上第一个alert输出的是undefined: 这是怎么回事呢? 要探讨这个问题首先要解释下两个概念: 1:函

浅谈js中函数作用域问题(一)

本人学习js时间并不长,前几天,写一段js代码时,在js指定一个按钮事件的匿名函数中加入一个同级函数,具体代码可见如下: var mainOb=document.getElementById("divObject");                                        var start=document.getElementById("start"); var a=10; start.onclick=funcrion(){ functi

javascript中函数作用域和声明提前

javascript不像java等其他强类型语句,没有块级作用域(括号内的代码都有自己的作用域,变量在声明它们的代码段之外不可见)一说,但有自己的独特地方,即函数作用域. 函数作用域:变量在声明它们的函数体内以及这个函数体的任意内部函数体内是有定义的. 如下所示代码,在不同位置定义了变量i.j和k,它们都在同一个作用域内,即在函数体内均是有定义的. function test(){ var i=0; //i在整个函数体内均有定义 if(true){ var j=0; //j在整个函数体内均有定义

《你不知道的JavaScript》 函数作用域和块级作用域

一.函数作用域 可用在代码外添加包装函数,将内部的变量和函数定义隐藏. var a = 2; function foo() { // <- - 添加这一行 var a = 3; console.log( a ); //3 } // <- - 以及这一行 foo(); // <- - 以及这一行 console.log( a ); //2 这种技术必须声明一个具名函数foo(),foo本身“污染”了所在作用域.其次,必须显式地通过函数名( foo( ) )调用这个函数才能运行其中的代码.