欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python学习Day10

程序员文章站 2024-02-24 15:05:52
...

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
相关标签: Python学习 python

上一篇: java学习(Day10)

下一篇: python day1