Python学习日记(八)
作用域
局部变量:
-
- 在函数中定义的参数和变量称为局部变量,仅在函数体内有效,出了函数体就无效,在函数外不能访问函数内定义的变量。
全局变量:
-
- 在函数外定义的变量为全局变量,作用域为整个代码文件,在函数中可访问全局变量;
- 使用全局变量时要小心,当试图在函数中访问并修改全局变量的值时Python会自动创建一个名字和全局变量一样的局部变量,但是全局变量的值并未改变,且两个变量不会互相影响。可以访问全局变量但不要在函数内部修改全局变量。
-
def discount(price,rate): final_price=price*rate old_price=50 print("修改后的old_price1:",old_price) return final_price old_price=float(input("请输入原价:")) rate=float(input("请输入折扣率:")) new_price=discount(old_price,rate) print("修改后的old_price2:",old_price) print("打折完的价格是:",new_price) 请输入原价:100 请输入折扣率:0.8 修改后的old_price1: 50 修改后的old_price2: 100.0 打折完的价格是: 80.0
global关键字:
-
- 想要在函数中修改全局变量的值可以使用global关键字
def discount(price,rate): final_price=price*rate global old_price old_price=50 print("修改后的old_price1:",old_price) return final_price old_price=float(input("请输入原价:")) rate=float(input("请输入折扣率:")) new_price=discount(old_price,rate) print("修改后的old_price2:",old_price) print("打折完的价格是:",new_price) 请输入原价:100 请输入折扣率:0.8 修改后的old_price1: 50 修改后的old_price2: 50 打折完的价格是: 80.0
- 想要在函数中修改全局变量的值可以使用global关键字
内嵌函数和闭包
内嵌函数:
-
- 可以在函数中定义函数;
- 内部函数整个作用域都在外部函数之内,出了外部函数就不能在外部访问和调用内部函数。
-
>>> def fun1(): print("func1正在被调用...") def func2(): print("func2正在被调用...") func2() >>> fun1() func1正在被调用... func2正在被调用...
闭包:
-
- 在内部函数里对外部作用域(不是全局作用域)的变量进行引用,内部函数被认为闭包;
- 在外部也不能调用闭包函数,同时在闭包中也不能修改外部函数变量的值但是可以访问,因为外部函数的变量在闭包的作用域之外,在执行闭包函数时外部函数是被屏蔽起来的,这个时候修改外部函数的变量就会报变量未定义。(类似全局变量和局部变量)
-
>>> def funx(x): def funy(y): return x*y return funy >>> i=funx(8) >>> i <function funx.<locals>.funy at 0x000001B5B3315EE0> >>> i(9) 72 >>> funx(8)(9) 72 #不能修改外部变量 >>> def funx(): x=5 def funy(): x+=3 return x return funy() >>> funx() Traceback (most recent call last): File "<pyshell#23>", line 1, in <module> funx() File "<pyshell#22>", line 6, in funx return funy() File "<pyshell#22>", line 4, in funy x+=3 UnboundLocalError: local variable 'x' referenced before assignment
-
- 若要修改外部变量可以把变量存在列表里,因为容器不会屏蔽变量;
-
>>> def funx(): x=[5] def funy(): x[0]=x[0]+3 return x[0] return funy() >>> funx() 8 - 还可以使用nonlocal关键字实现外部变量的修改。
>>> def funx(): x=5 def funy(): nonlocal x x=x+3 return x return funy() >>> funx() 8
lambda表达式:
-
- 使用lambda表达式可以省下定义函数的过程,使代码更精简,适合简单的脚本编写。
-
>>> lambda x,y:3*x+y <function <lambda> at 0x00000195EE5B5A60> >>> g=lambda x,y:3*x+y >>> g(3,1) 10
介绍两个复杂内置函数(BIF):
filter()(过滤器):
-
- 保留重要的东西,过滤无用的多余信息,即过滤掉非True内容,返回一个对象,可用list将对象转化为列表
-
#传入两个参数,一个是函数或none,一个是可迭代的对象,返回一个过滤过的可迭代的对象 >>> 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. | >>> def F(x): return x%2 >>> s=filter(F,range(10)) >>> s <filter object at 0x00000195EE5ABFA0> >>> list(s) [1, 3, 5, 7, 9] 上述代码等价于 >>> list(filter(lambda x:x%2,range(10))) [1, 3, 5, 7, 9]
map()(映射):
-
- 参数和filter()一样,作用是将可迭代序列的每一个数作为函数的参数进行运算加工,直到所有元素都加工完毕,返回加工后的新序列。
>>> list(map(lambda x:x*2,range(10))) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
- 参数和filter()一样,作用是将可迭代序列的每一个数作为函数的参数进行运算加工,直到所有元素都加工完毕,返回加工后的新序列。
例题:
1、编写一个函数,判断传入的字符串参数是否为“回文联”
-
方法一: def palindrome(string): length = len(string) last = length-1 length //= 2 flag = 1 for each in range(length): if string[each] != string[last]: flag = 0 last -= 1 if flag == 1: return 1 else: return 0 string = input('请输入一句话:') if palindrome(string) == 1: print('是回文联!') else: print('不是回文联!') 方法二: def H(s): list1=list(s) list2=reversed(list1) if list1==list(list2): print("是回文") else: print("不是回文") s=input("请输入字符串:") H(s)
2、编写一个函数,分别统计出传入字符串参数(可能不只一个参数)的英文字母、空格、数字和其它字符的个数。
-
#统计一个参数: def Count(s): x=0 y=0 z=0 k=0 lx=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] ly=[' '] lz=['0','1','2','3','4','5','6','7','8','9'] ss=list(s) l=len(s) i=0 for i in range(l): if ss[i].lower() in lx: x=x+1 elif ss[i] in ly: y=y+1 elif ss[i] in lz: z=z+1 else: k=k+1 print("英文字母个数:%d\n空格个数:%d\n数字个数:%d\n其他字符个数:%d\n"%(x,y,z,k)) s=input("请输入字符串:") Count(s) #统计很多参数 def count(*param): length = len(param) for i in range(length): word = 0 num = 0 spa = 0 oth = 0 for j in param[i]: if j.isalpha(): word += 1 elif j.isspace(): spa += 1 elif j.isdigit(): num += 1 else: oth += 1 print('第 %d 个字符串共有:英文字母 %d 个,数字 %d 个,空格 %d 个,其他字符 %d 个' % (i + 1, word, num, spa, oth)) count('I love fish.com 123', 'I love you', 'you love 123')
3、请将下边的匿名函数转变为普通函数?
lambda x:x if x%2 else None
-
def odd(x): if x%2: return x else: return None
4、用filter()函数和lambda表达式快速求出100以内所有3的倍数?
-
a = list(filter(lambda x:x%3 == 0,range(1,100))) print(a) b = list(filter(lambda x:not(x%3),range(1,100))) print(b) c = list(filter(lambda x:x if x%3==0 else None,range(100))) print(c)
5、还记得zip吗?使用zip会将两数以元祖的形式绑定在一块(如下代码),但如果我希望打包的形式是灵活多变的列表而不是元祖(希望是[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]这种形式),你能做到吗?(采用map和lambda的表达式)
-
>>> list(zip([1,3,5,7,9],[2,4,6,8,10])) [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)] list(map(lambda x,y : [x,y],[1,3,5,7,9],[2,4,6,8,10]))
总结:
- 函数与过程:过程(procedure)是简单的,特殊且没有返回值的;函数(Function)有返回值,Python严格来说只有函数没有过程
- 返回值可以是一个int类型,可以返回一个列表,可以返回一个元组
- 局部变量:在局部生效如在函数中定义的变量
- 全局变量:作用于整个模块。函数内若试图修改全局变量,Python会新建一个同名局部变量用于存储修改值,原全局变量的值不变

浙公网安备 33010602011771号