Python学习Day10
Python学习Day10
global关键字
不要试图去修改全局变量,如果你试图去修改全局变量的话,Python就会使用屏蔽(Shadowing)的方式去保护全局变量,即在函数内部自动创建一个局部变量。
>>> count = 5
>>> def PP():
count = 10
print(count)
>>> PP()
10
>>> print(count)
5
>>> #count在函数PP中已被Shadowing成局部变量
如果有必要坚持在函数中去修改全局变量的话,我们可以使用global关键字来达到目的。
>>> def PP():
global count
count = 10
print(count)
>>> PP()
10
>>> print(count)
10
>>> #这里使用global关键字将count在函数中就变成全局变量了
内嵌函数
>>> def fun1():
print("fun1()正在被调用...")
#注意内嵌函数的缩进与print是同一级别的
def fun2():
print("fun2()正在被调用...")
fun2()
>>> fun1()
fun1()正在被调用...
fun2()正在被调用...
>>> #这是函数嵌套的最简单的例子
N.B.
内部函数整个作用域都在外部函数之内,例如,fun2()整个定义和调用的过程都在fun1()里边,出了fun1(),就没有任何可以对fun2()进行调用的方式了
闭包(closure)
不同的编程语言闭包的方式不同,Python中闭包从表现形式上定义为如果在一个内部函数里对外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。
>>> def FunX(x):
def FunY(y):
return x * y
return FunY
>>> i = FunX(5)
>>> i
<function FunX.<locals>.FunY at 0x000002372169C3A0>
>>> type(i)
<class 'function'>
>>> i(8)
40
>>> FunX(8)(5)
40
>>> #上述的例子中,funY()就属于内部函数,其在对外部作用域(但不是全局作用域)的变量进行了引用(x就是被引用的变量,x在外部作用域funX()函数里面,但不在全作用域里),则这个内部函数就是一个闭包。
N.B.
因为闭包的概念是由内部函数而来,所以不能在外部函数以外的地方对内部函数进行调用
>>> def Fun1():
x = 5
def Fun2():
x *= x
return x
return Fun2()
>>> Fun1()
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
Fun1()
File "<pyshell#18>", line 6, in Fun1
return Fun2()
File "<pyshell#18>", line 4, in Fun2
x *= x
UnboundLocalError: local variable 'x' referenced before assignment
>>> #这里程序报错了,因Fun1()最终返回的Fun2(),而Fun2()整个的外部的空间就是Fun1()的内部空间,x为非全局变量的外部变量,Fun2()修改了x,相当于修改了Fun2()的全局变量,那么外面的全局变量x=5就会被Shadowing,x的值就无法获得
改进思路:如果试图对一个没有定义的数据进行平方的操作,在Python3之前,我们只能间接地通过容器类型的存放,因为容器类型不是存放在栈里边,所以x不会被Shadowing.
容器类型:字符串、列表、元组等
>>> def Fun1():
x = [5]
def Fun2():
x[0] *= x[0]
return x[0]
return Fun2()
>>> Fun1()
25
nonlocal关键字
如果希望在内部函数里可以修改外部函数里的局部变量的值,可以使用nonlocal关键字声明x不是一个局部变量,使用方法和global一样
>>> def Fun1():
x = 5
def Fun2():
nonlocal x
x *= x
return x
return Fun2()
>>> Fun1()
25
lambda表达式
Python允许使用lambda关键字来创建匿名函数。
>>> #先创建一个普通的函数
>>> def ds(x):
return 2 * x + 1
>>> ds(5)
11
>>> #使用lambda语句来定义这个函数
>>> lambda x : 2 * x + 1
<function <lambda> at 0x000002246F61C3A
>>> g = lambda x : 2 * x + 1
>>> g(5)
11
>>> def add(x,y):
return x+y
>>> add(3,4)
7
>>> lambda x,y : x + y
<function <lambda> at 0x000002246F61C430>
>>> g = lambda x,y : x + y
>>> g(3,4)
7
lambda表达式的基本语法就是使用冒号(:)分隔函数的参数及返回值:冒号左边放置函数的参数,如果有多个参数,使用逗号隔开即可;冒号右边是函数的返回值。
两个牛逼的BIF
filter()
filter()函数是一个过滤器,它的作用就是从海量的数据中提取出有用的信息。
>>> help(filter)Help on class filter in module builtins:class filter(object) | filter(function or None, iterable) --> filter object | | Return an iterator yielding those items of iterable for which function(item) | is true. If function is None, return the items that are true. | | Methods defined here: | | __getattribute__(self, name, /) | Return getattr(self, name). | | __iter__(self, /) | Implement iter(self). | | __next__(self, /) | Implement next(self). | | __reduce__(...) | Return state information for pickling. | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) from builtins.type | Create and return a new object. See help(type) for accurate signature.
总的来说,filter()有两个参数:第一个参数可以是函数也可以是None,如果是一个函数的话,则将可迭代对象里的每一个元素作为函数的参数进行计算,把返回的True的值筛选出来;如果第一个参数为None,则直接将第二个参数中为True的值筛选出来
>>> filter(None,[0,1,False,True])<filter object at 0x000002174CB46340>>>> list(filter(None,[0,1,False,True]))[1, True]>>> #定义过滤的函数>>> def odd(x): return x % 2>>> temp = filter(odd,range(10))>>> list(temp)[1, 3, 5, 7, 9]>>> list(filter(lambda x: x % 2,range(10)))[1, 3, 5, 7, 9]
map()
映射函数
>>> list(map(lambda x: x * 2,range(10)))[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]>>> #map()的第二个参数是收集参数,支持多个可迭代对象。map()会从所有可迭代对象中依次取一个元素组成一个元组,然后将元组传递给func。注意:如果可迭代对象的长度不一致,则以较短的迭代结束为止。>>> list(map(lambda x , y : x + y,[1,3,5],[10,30,50,70,90]))[11, 33, 55]
递归
>>> #设置递归的深度>>> import sys>>> sys.setrecursionlimit(10000)>>> #将递归深度限制设置为一万层
求一个阶乘的函数
>>> #非递归版本>>> def recursion(n): result = n for i in range(1,n): result *= i return result>>> recursion(5)120>>> recursion(6)720
#阶乘版本def factorial(n): if n == 1: return 1 else: return n * factorial(n-1)number = int(input("请输入一个整数:"))result = factorial(number)print("%d 的阶乘是: %d" %(number,result))请输入一个整数:55 的阶乘是: 120 请输入一个整数:66 的阶乘是: 720
以上程序满足了递归的两个条件:
- 调用函数本身
- 设置了正确的返回条件
递归口诀:递归递归,归去来兮
斐波那契数列
特点:第一第二个数都是为1,而后面的每一个数都是为前两个数的和,而越往后推,每两个相邻数之间的商都无限接近0.618
用函数来定义斐波那契数列:
用迭代实现:
#用迭代实现斐波那契数列def fab(n): n1 = 1 n2 = 1 n3 = 1 if n < 1: print('输入有误!') return -1 while (n - 2) > 0: n3 = n2 + n1 n1 = n2 n2 = n3 #循环的次数就可以减一 n -= 1 return n3result = fab(3)if result != -1: print('总共有%d对小兔子诞生!'%result) ======================== RESTART: E:/Python/迭代-斐波那契数列.py =======================总共有6765对小兔子诞生!
用递归实现:
def fab(n): if n < 1: print('输入有误!') return -1 if n == 1 or n == 2: return 1 else: return fab(n-1) + fab(n-2)result = fab(20)if result != -1: print('总共有%d对小兔子诞生!'% result) ======================== RESTART: E:/Python/递归-斐波那契数列.py =======================总共有6765对小兔子诞生!
汉诺塔
def hanoi(n,x,y,z): if n == 1: print(x,'-->',z) else: hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上 print(x,'-->',z)# 将最底下的一个盘子从x移动到z上 hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上n = int(input('请输入汉诺塔的层数:'))hanoi(n,'x','y','z') 请输入汉诺塔的层数:4x --> yx --> zy --> zx --> yz --> xz --> yx --> yx --> zy --> zy --> xz --> xy --> zx --> yx --> zy --> z
上一篇: java学习(Day10)
下一篇: python day1