zoukankan      html  css  js  c++  java
  • Python基础及语法(五)

    Python函数

     函数

    数学定义:y=f(x),y是x的函数,x是自变量。

    Python函数定义:由若干语句组成的语句块,函数名称,参数列表构成,它是组织代码的最小单元,完成一定功能。

    函数的作用:结构化编程对代码最基本的封装,一般按照功能组织一段代码,封装后便于重复使用,使代码更加简洁美观。

    函数的分类:内建函数,如:max(),库函数,如:random.randint(),自定义函数,使用def关键字定义。

    1 # 名称为自定义标识符,括号里定义形参(形参可以用'='加入缺省值,一个'*'收集多个位置参数组织到元组中,两个'*'收集多个关键字参数组织到字典中,只能放最后)
    2 def f(a, b=7, *args, c, d=8, **kwargs):  # 一个'*'后只能使用关键字传参,Python3.8后增加符号为'/','/'前的参数必须用位置传参的方式,不能使用关键字传参
    3     print(a, b, c, d)  # 1 2 4 8
    4     print(args)  # (3,),如果没接收到元素返回空元组
    5     print(kwargs)  # {'e': 5, 'f': 6},如果没接收到元素返回空字典
    6     return type(a), type(args), type(kwargs)  # 返回一个元组,如果不写return返回None。在函数中执行到return后立刻跳出当前函数,返回
    7 # 调用f函数,函数必须在调用前定义好,否则NameErrors,传入实参(分为位置传参与关键字传参,关键字传参必须在位置传参后面,不能重复传入参数)
    8 y = f(*[1, 2], 3, **{'c': 4, 'e': 5}, f=6)  # 一个'*'解构位置传参,如果结构的是集合注意无序,两个'*'解构关键字传参Python3.6版本后字典记录录入顺序
    9 print(y)  # (<class 'int'>, <class 'tuple'>, <class 'int'>, <class 'dict'>),y接受f函数返回的元素

     函数作用域

    一个标识符的可见范围就是该标识符的作用域。作用域分为全局作用域和局部作用域,全局作用域在整个程序运行环境中可见,称为全局变量,局部作用域在函数,类等内部可见,称为本地变量。

    嵌套函数

    函数里面定义了另一个函数,外部的函数看不见里面的函数变量,里面的函数赋值右边需要用到的变量在里面没有被定义时,会在最近的外部范围找,赋值左边的标识符均定义为局部变量,只能在内部寻找。

    global

    在函数里使用该语句声明该变量为全局变量,尽量不要使用。

    nonlocal

    在函数里使用该语句声明该变量在最近的外部函数。

    闭包

    出现在嵌套函数中,内层函数用到了外层函数的变量,就形成了闭包。

    匿名函数:lambda表达式

    没有名字的函数是为匿名函数。

    1 print((lambda x, y: x+y)(1, 2))  # 3,lambda后面跟参数,冒号后面是函数表达式,只能写一行,通常用于高阶函数,后面是传参内容,通常不用这种方式传参

     递归函数

    函数的执行流程跟栈有关,后入先出。递归函数是间接或直接调用函数自身,递归有深度限制,运行效率相对低,绝大多数递归都可用循环实现,能不用递归则不用。

    1 def fib_(n, a=0, b=1):  # 斐波那契数列递归
    2     return b if n == 1 else fib_(n-1, b, a+b)
    3 
    4 
    5 print(fib_(101))  # 573147844013817084101

     生成器函数

    生成器除了用生成器表达式外,还可以使用生成器函数,函数中存在yield语句的函数算是生成器函数,返回生成器对象。

     1 def fib(a=0, b=1):  # 斐波那契数列生成器函数
     2     def inc():
     3         nonlocal a, b
     4         a, b = b, a+b
     5         yield a
     6     return lambda: next(inc())
     7 
     8 
     9 f = fib()
    10 for i in range(5):
    11     print(f())  # 1 1 2 3 5

    生成器交互

    python提供了生成器交互的方法send,该方法可以与生成器沟通

    def counter():
        def inc():
            a = 0
            while True:
                a += 1
                b = yield a
                if b is not None:
                    a = 0
        c = inc()
        return lambda d=False: c.send(0) if d else next(c)
    
    
    f = counter()
    print(f())  # 1
    print(f())  # 2
    print(f())  # 3
    print(f(True))  # 1
    print(f())  # 2

    yield from

     1 def counter():  # 一种简化语法的方法
     2     def inc():
     3         yield from range(1000)
     4     c = inc()
     5     return lambda: next(c)
     6 
     7 
     8 f = counter()
     9 print(f())  # 0
    10 print(f())  # 1
    11 print(f())  # 2

    高阶函数

    数学概念:y = f(g(x))

    接受一个或多个函数做参数,或输出一个函数的是为高阶函数。

    内建高阶函数

    1 print(sorted(['a', 'd', 1, 11, 22], key=lambda x: int(x, 16) if isinstance(x, str) else x))  # [1, 'a', 11, 'd', 22],按十六进制排序
    2 print(list(filter(lambda x: x % 3 == 0, range(10))))  # [0, 3, 6, 9],过滤能被3整除的数
    3 print(list(map(str, range(5))))  # ['0', '1', '2', '3', '4'],映射0-4为文本

    插入排序

     1 def sorted_1(ls):
     2     for i in range(1, len(ls)):
     3         a = ls[i]
     4         for j in range(i-1, -1, -1):
     5             if a < ls[j]:
     6                 ls[j+1] = ls[j]
     7             else:
     8                 ls[j+1] = a
     9                 break
    10         else:
    11             ls[0] = a
    12     return ls
    13 
    14 
    15 arr = [5, 2, 4, 6, 1, 3]
    16 print(sorted_1(arr))  # [1, 2, 3, 4, 5, 6]
     1 def sorted_2(ls):
     2     ls = [0] + ls
     3     for i in range(1, len(ls)):
     4         ls[0], j = ls[i], i-1
     5         while ls[j] > ls[0]:
     6             ls[j + 1], j = ls[j], j-1
     7         else:
     8             ls[j + 1] = ls[0]
     9     return ls[1:]
    10 
    11 
    12 arr = [5, 2, 4, 6, 1, 3]
    13 print(sorted_2(arr))  # [1, 2, 3, 4, 5, 6]

    定义

    树(tree)是包含n(n>=0)个结点的有穷集,其中:

    (1)每个元素称为结点(node);
    (2)有一个特定的结点被称为根结点或树根(root)。
    (3)除根结点之外的其余数据元素被分为m(m≥0)个互不相交的集合T1,T2,……Tm-1,其中每一个集合Ti(1<=i<=m)本身也是一棵树,被称作原树的子树(subtree)。
    树也可以这样定义:树是由根结点和若干颗子树构成的。树是由一个集合以及在该集合上定义的一种关系构成的。集合中的元素称为树的结点,所定义的关系称为父子关系。父子关系在树的结点之间建立了一个层次结构。在这种层次结构中有一个结点具有特殊的地位,这个结点称为该树的根结点,或称为树根。
    我们可以形式地给出树的递归定义如下:
    单个结点是一棵树,树根就是该结点本身。
    设T1,T2,..,Tk是树,它们的根结点分别为n1,n2,..,nk。用一个新结点n作为n1,n2,..,nk的父亲,则得到一棵新树,结点n就是新树的根。我们称n1,n2,..,nk为一组兄弟结点,它们都是结点n的子结点。我们还称T1,T2,..,Tk为结点n的子树。
    空集合也是树,称为空树。空树中没有结点。

    名词解释

    结点的度:一个结点含有的子结点的个数称为该结点的度;
    叶结点或终端结点:度为0的结点称为叶结点;
    非终端结点或分支结点:度不为0的结点;
    双亲结点或父结点:若一个结点含有子结点,则这个结点称为其子结点的父结点;
    孩子结点或子结点:一个结点含有的子树的根结点称为该结点的子结点;
    兄弟结点:具有相同父结点的结点互称为兄弟结点;
    树的度:一棵树中,最大的结点的度称为树的度;
    结点的层次:从根开始定义起,根为第1层,根的子结点为第2层,以此类推;
    树的高度或深度:树中结点的最大层次;
    堂兄弟结点:双亲在同一层的结点互为堂兄弟;
    结点的祖先:从根到该结点所经分支上的所有结点;
    子孙:以某结点为根的子树中任一结点都称为该结点的子孙。
    森林:由m(m>=0)棵互不相交的树的集合称为森林。

    特点

    唯一的根

    子树不相交

    可以有0个或多个后继,除了根以外,只能有1个前驱

    根没有前驱,叶子结点没有后继

    双亲比孩子的层次小1

    二叉树

    在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

    满二叉树

    一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是(2^k) -1 ,则它就是满二叉树。

    完全二叉树

    完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。

    性质:

    如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与深度为k的满二叉树中编号为1~n的结点一一对应,这棵二叉树称为完全二叉树。
    可以根据公式进行推导,假设n0是度为0的结点总数(即叶子结点数),n1是度为1的结点总数,n2是度为2的结点总数,则 :
    ①n= n0+n1+n2 (其中n为完全二叉树的结点总数);又因为一个度为2的结点会有2个子结点,一个度为1的结点会有1个子结点,除根结点外其他结点都有父结点,
    ②n= 1+n1+2*n2 ;由①、②两式把n2消去得:n= 2*n0+n1-1,由于完全二叉树中度为1的结点数只有两种可能0或1,由此得到n0=n/2 或 n0=(n+1)/2。
    简便来算,就是 n0=n/2,其中n为奇数时(n1=0)向上取整;n为偶数时(n1=1)向下取整。可根据完全二叉树的结点总数计算出叶子结点数。
     
    特点:
    叶子结点只可能在最大的两层上出现,对任意结点,若其右分支下的子孙最大层次为L,则其左分支下的子孙的最大层次必为L 或 L+1;
    出于简便起见,完全二叉树通常采用数组而不是链表存储,其存储结构如下:
    var tree:array[1..n]of longint;{n:integer;n>=1}
    对于tree[i]有如下特点:
    (1)若i为奇数且i>1,那么tree的左兄弟为tree[i-1];
    (2)若i为偶数且i<n,那么tree的右兄弟为tree[i+1];
    (3)若i>1,tree的父亲节点为tree[i div 2];
    (4)若2*i<=n,那么tree的左孩子为tree[2*i];若2*i+1<=n,那么tree的右孩子为tree[2*i+1];
    (5)若i>n div 2,那么tree[i]为叶子结点(对应于(3));
    (6)若i<(n-1) div 2.那么tree[i]必有两个孩子(对应于(4))。
    (7)满二叉树一定是完全二叉树,完全二叉树不一定是满二叉树。
    完全二叉树第i层至多有2^(i-1)个节点,共i层的完全二叉树最多有2^i-1个节点。
    完全二叉树的特点是:
    1)只允许最后一层有空缺结点且空缺在右边,即叶子结点只能在层次最大的两层上出现;
    2)对任一结点,如果其右子树的深度为j,则其左子树的深度必为j或j+1。 即度为1的点只有1个或0个
  • 相关阅读:
    向量空间模型 词袋模型
    python 小点
    python list的append()和extend()方法
    numpy 数组运算
    内置函数和numpy中的min(),max()函数
    python index()函数
    Python支持的正则表达式元字符和语法
    Python多线程
    查看linux机器配置&内核版本
    Shell获取文件的文件名和扩展名的例子
  • 原文地址:https://www.cnblogs.com/bgr1115/p/12691965.html
Copyright © 2011-2022 走看看