《Python3 从入门到实战》第三章函数(易忘知识点+实例)

3.1 定义函数、调用函数、参数传递

3.1.1 定义函数和调用函数

通过关键字def定义函数。

圆括号中可以包含一些成为“参数”的变量,圆括号中包含的参数变量成为函数的“参数列表”(参数列表可以是空的,即不包含任何参数),圆括号的后面是一个冒号:。从def关键字一直到该行结尾的冒号构成了函数头。函数头下面的是一组语句构成的语句块,称为函数体

3.1.2 参数传递

圆括号中的参数:形式参数(形参)

调用函数时传递的参数:实际参数(实参)

3.1.3 return语句

1.最大公约数

def GCD(m,n):
    while n!=0:
        m,n=n,m%n
    return m

2.返回多个值

return可以返回多个值,这些值被包裹在一个turple对象中返回。

3.1.4 文档字符串

在函数头后面添加由三个引号(三个单引号或三个双引号)括起来的文档字符串(docstring),用于说明这个函数的功能。docstring作为函数对象的一个属性"__doc__"被使用。

打印文档字符串的内容:


print(hi.__doc__)   # hi为定义的函数名

3.2 全局变量和局部变量

3.2.1 全局变量

函数外部声明的变量。在函数内部和外部都能用。

在函数内部修改全局变量:

x="global"
def fun():
    global x
    x=x*2
    print(x)

fun()

3.22 局部变量

在函数内部定义一个变量,这个变量只属于该函数,外部无法使用这个变量。

如果函数内部声明的局部变量和外部变量同名,则内部的局部变量会隐藏全局变量,即在函数内部使用这个名字访问的总是全局变量。

3.3 函数的参数

3.3.1 默认形参

函数的形参可以有默认值,调用函数时如果没有为默认形参提供实际参数,则该形参就取默认值。

如果一个函数的形参中既有默认形参又有非默认形参,则默认形参必须都在非默认形参的后面,默认形参后面不能再有非默认形参。

i=5
def f(arg=i):
    print(arg)

i=6
f()  # 将输出:5

3.3.2 位置实参和关键字实参

位置实参:函数定义中的形参是有顺序的,调用函数时传递的实参是按照顺序为对应位置的形参赋值的。

关键字实参:形参名=实参

3.3.3 任意形参(可变形参)

在定义函数时不知道将来使用者调用这个函数时传递的实际参数个数,在形参名前加一个星号*。

def hello(*names):
    print("哈喽:")
    for name in names:
        print(name)
    print()

函数中的可变形参最多只能有一个,不能有两个可变形参。

3.3.4 字典形参

字典形参名前面有两个**,这个形参指向的是一个dict对象,调用函数时必须以"key=value"的形式传递可变参数的实参,这些实参被组装成一个dic对象,并赋值给字典形参。

如果函数定义中既有可变形参又有字典形参,则字典形参必须位于可变形参的后面。

函数中的字典形参最多只能有一个,不能有两个字典形参。

3.3.5 解封参数列表

例:

def add(x,y):
    return x+y

可以调用的方式:

print(add(3,5))

ab=[3,5]
print(add(ab[0],ab[1]))
print(add(*ab))  # 解封实参列表

假设参数在一个字典中,要用两个星号**把它们分离出来。

3.4 递归函数(调用自身的函数)

3.4.1 递归函数的使用方法

1.递归函数

递归是一种将任务分解的解决问题的方法。

求n的阶乘:

def fact(n):                
    if n==1:
        return 1
    return n*fact(n-1)    # 如果n大于1,就是n和fact(n-1)的乘积
fact(4)

2.斐波那契数列

又称黄金分割数列或“兔子数列”。

def fib(n):
    if n<=2:
        return 1
    else:
        return fib(n-1)+fib(n-2)

for i in range(8):
    print(fib(i),end=',')

3.4.2 二分查找的递归实现

def binarySearch(alist,value):
    if len(alist)==0:                                        #(0)空序列
        return -1
    else:
        Middle=len(alist)//2
        if alist[Middle]==value:                             #(1)中间元素直接比较
            return Middle
        else:
            if value<alist[Middle]:
                return binarySearch(alist[:Middle],value)    #(2)左区间查找
            else:
                return binarySearch(alist[Middle+1:],value)  #(3)右区间查找

3.4.3 实战:汉诺塔问题

a,b,c三根柱子,a柱子上有n个盘子,盘子尺寸从上到下依次变大。要求把盘子全部移到c柱子,每次只能移动一个盘子,小盘必须在大盘之上。

# 一个盘子:直接移动
def moveDisk(i,x,y):
    print("moving disk",i,"from",x,"to",y)

# 盘子数,起始柱,中转柱,目标柱
def move(n,a,b,c):
    if n>=1:
        move(n-1,a,c,b)    #n-1个盘子从a柱子借助c柱子移到b柱子
        moveDisk(n,a,c)    #第n号盘子直接从a柱子移到c柱子
        move(n-1,b,a,c)    #n-1个盘子从b柱子借助a柱子移到c柱子

3.4.4实战:快速排序算法

思想:在这组数中任取一个数作为“基准”,将这组数分为两部分,其中一部分的所有数不大于基准元素,而另一组所有数不小于基准数。重复上述过程。

快速排序算法qsort:

#对[start,end]区间的元素进行快速排序
def qsort(arr,start,end):
    if start<end:
        pivot=partition(arr,start,end)  #将[start,end]之间的序列一次划分为两部分
                                        #pivot是基准的位置
        qsort(arr,start,pivot-1)        #对[start,pivot-1]之间的序列调用qsort进行快速排序过程
        qsort(arr,pivot+1,end)          #对[pivot+1,end]之间的序列调用qsort进行快速排序过程

partition()代码:

def partition(alist,start,end):
    pivotvalue=alist[start]    #假设选择start的元素为基准元素,并暂存到pivotvalue中
    L=start+1                  #左指示器指向区间左侧
    R=end                      #右指示器指向区间右侧


    done=False
    while not done:
        while L<=R and alist[L]<=pivotvalue:
            L=L+1

        while alist[R]>=pivotvalue:
            R=R-1


        if R<l:
            done=True
        else:
            alist[L],alist[R]=alist[R],alist[L]
            #temp=alist[L]
            #alist[L]=alist[R]
            #alist[R]=temp
#R<L时的位置R就是基准元素的目标位置
    alist[R],alist[start]=alist[start],alist[R]    #交换基准元素和R位置的元素
    return R        #返回基准元素的位置

3.5 函数对象和lambda表达式

3.5.1 函数对象

1.函数也是对象

函数是function类型的对象。

函数可以存储在各种数据结构中。

2.函数可以放在容器内

如:可以放在字典里,通过for...in循环遍历,并调用字典元素的值指向的函数。

3.函数可以作为返回值

4.函数可以嵌套

嵌套函数不能修改包围环境中的变量,除非该变量在嵌套函数中被声明为nonlocal。

但如果在函数中声明了“nonlocal”,则这个x将是该函数的包围环境,nonlocal类似global。

5.函数可以作为其他函数的参数

3.5.2 lambda表达式

1.lambda表达式(匿名函数)

不用关键字def定义的没有函数名的函数,主要用于定义简单的单行函数,即代码可以写在一行里,和普通函数一样,可以有参数列表。

add=lambda x,y:x+y

2.lambda函数功能

主要用作函数的参数。

print(sorted(alist,key=lambda x:abs(x)))
alist=[(2,2),(3,4),(4,1),(1,3)]
alist.sort(key=lambda e:e[1])
print(alist)

3.内置函数map()和内置函数filter()

(1)内置函数map()
map(function,*iterable)

iterable是可变形参,即可以接收多个可迭代对象。内置函数map()将第一个参数function指向的函数对象作用于每个可迭代对象的每个数据元素上。

(2)内置函数filter()
filter(function or None,iterable)

接收一个函数(或空值对象)和一个可迭代对象,返回一个新的迭代器对象。

3.6 模块和包

3.6.1 模块

1.模块

函数是可以重复调用的程序块。python模块就是包含python语句的、文件名后缀(文件拓展名)是.py的文件。

2.导入(import)模块

import 模块名

导入的模块只要说明模块名即可,不能有文件拓展名.py

3.重命名导入模块

可以用“import...as”对一个导入进来的模块进行重命名。

4.导入单独名字

可以用“from...import”从一个模块导入一个单独的名字。

5.导入所有的名字

还可以通过"from...import*"导入模块中的所有名字,该模块中的名字就可以直接使用,而不再需要模块名前缀了。

6.函数dir

dir([object])

7.函数help()

函数help()打印一个对象的帮助信息。

8.模块的__name__属性

每一个模块都有一个__name__属性。

if(__name__=='__main__')

判断脚本是否在主程序执行↑

3.6.2 sys模块(python解释器接口)

负责与python解释器的交互,提供一系列的函数和变量,用于操控python的运行时环境。

1.sys.argv

编写一个叫做abc.py的脚本:

import sys
print('脚本名:',sys.argv[0])

在python解释器中执行这个脚本:

python abc.py

2.sys.path(模块搜索路径)

是一个字符串列表,用于指定模块的搜索路径,python解释器在导入模块时,会在这些路径中查找相应的模块。

3.sys.exit()(退出函数)

用于退出python的脚本程序,该函数可以带一个整数作为参数,用于表示程序退出的状态(不同的整数表示不同的退出情形)。

传递整数0表示正常退出。

如果要退出解释器而不是单个脚本程序,则可以使用内置函数exit(),该内置函数直接退出并关闭解释器。

4.sys.executable

保存python解释器的完整路径

5.sys.platform

值为平台标识符

import sys
sys.platform        #输出:'win32'

6.sys.getrefcount()

返回一个对象的引用计数,该计数通常比用户预期的多一个,因为包含对getrefcount()形参的临时引用。

7.sys.getsizeof()

返回一个对象占用的内存的字节数。

8.sys.stdin、sys.stdout、sys.stderr

分别映射到与解释器的标准输入、标准输出和错误流相对应的文件对象。

9.sys.getdefaultencoding()

获取系统当前编码,系统默认编码时UTF-8.

10.sys.setdefaultencoding()

设置系统默认编码。

3.6.3 伪随机数发生器模块

1.random模块

random.random()        生成[0.0,1.0)之间的浮点数

2.种子(seeding)

初始化随机数发生器,以便让它产生预期的一组值。

3.6.4 包

1.包

包含__init__.py文件

2.包的初始化

如果包含__init__.py文件,则在导入程序包或程序包中的模块时会执行该文件。该功能可以用于执行包初始化代码。

3.__all__变量

如果在__init__.py文件中定义了一个__all__变量,且该变量中包含一些模块名,那么使用import*,就会导入__all__变量中的模块中的所有对象。

4.子包

包中可以嵌套子包,子包中还可以嵌套子包的子包。

3.6.5 matplotlib包

绘图工具包。

pip install matplotlib

import matplotlib.pyplot as plt

plot()默认自动生成从0开始的横轴坐标。

title()起标题,legend()给每个绘制的曲线起一个名字。

xlim()、ylim()分别用于限定x和y坐标的范围。

xlabel()、ylabel()分配标签。

3.8 实战:线性回归

3.8.1 机器学习

基于规则的逻辑推理:典型代表专家系统。

基于统计模型的机器学习:采用一些统计模型,如支持向量机、核方法、随机森林、线性或逻辑回归模型、神经网络模型等,根据大量数据样本,学习出某种假设模型的参数,再利用这个模型对新数据进行预测。

3.8.2 假设函数、回归和分类

回归:要预测的目标变量y是一个连续的值的这种监督学习

分类:要预测的目标变量y是一个离散的值的这种监督学习

假设函数h(x)的集合通常是一个无穷集合,但可以用一组未知参数刻画这些函数。

回归的目标就是根据一组数据在某种最佳的意义上求出一个参数(如a、b)确定的假设函数,即确定那些未知参数。

3.8.3 线性回归

1.线性回归的含义

如果表示目标变量y和特征x之间的假设函数h(x)是一个线性函数,那么这种监督学习成为线性回归,即线性函数h(x)表示的是一个直线。

多特征值:表示为向量形式

3.8.4 多变量函数的最小值、正规方程

线性回归的代价函数是许多样本的误差累加和。

一般用迭代法求方程组的解,其中最常用的就是梯度下降法:从一个\theta的初始值出发,沿着梯度方向迭代更新未知参数\theta

3.8.5 梯度下降法

        就是从一个初始的\theta,迭代地沿着J关于\theta的梯度的反方向前进(更新\theta值),从而不断逼近最佳的\theta

  • 随机选择一组值作为\theta的初始值。
  • 循环迭代直至结果收敛

        \alpha是学习率,表示更新\theta的速度,太小则收敛缓慢,太大则可能会跳过最佳\theta,导致\theta值来回振荡。一般来说,这个学习率不是固定的,首先可以取较大值,以加快更新速度,然后逐渐减小,以提高收敛性。

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值