假期第(20)天
变量作用域与局部变量
l 变量起作用的代码范围称为变量的作用域,不同作用
域内变量名可以相同,互不影响
l 在函数内部定义的普通变量只在函数内部起作用,称
为局部变量。当函数执行结束后,局部变量自动删除
l 局部变量的引用比全局变量速度快,应优先考虑使用
l 如果局部变量与全局变量具有相同的名字,那么该局
部变量会在自己的作用域内隐藏同名的全局变量
>>> def demo():
x = 3
#局部变量x自动隐藏了同名的全局变量
>>> x = 5
>>> x
5
>>> demo()
>>> x
#函数执行不影响外面全局变量的值
5
变量作用域3
32
2
全局变量-1
l 全局变量分为两种情况:
l 全局变量已在函数外定义,函数内可用global对其声明操作
l 在函数内部也可直接通过关键字global定义全局变量
l 也可以这么理解:
l 在函数内可以直接引用全局变量
l 若在函数内为变量赋新值,
该
变
量即被视为局部变量,除非
在函数内显式地用关键字
g
lo
ba
l进行声明
>>> def demo():
global x
x = 3
#全局变量
y = 4
#局部变量
>>> x = 5
>>> demo()
>>> x
3
>>> del x
>>> demo()
>>> x
变量作3用域3
3
3
3
全局变量-2
l 如果需要在同一个程序的不同模块之间共享全局变量
的话,可以编写一个专门的模块来实现这一目的。例
如,假设在模块A.py中有如下变量定义:
global_variable = 0
l 而在模块B.py中包含以下用来设置全局变量的语句:
import A
A.global_variable = 1
l 在模块C.py中有以下语句来访问全局变量的值:
import A
print(A.global_variable)
变量作用域3
34
4
lambda表达式
l lambda表达式尤其适合作为函数参数的场合
l lambda表达式只可以包含一个表达式,其结果可看作
是返回值,不允许包含复合语句,但可调用其他函数
>>> g = lambda x, y=2, z=3: x+y+z#可起名,参数默认值
>>> g(1)
#像函数一样调用
6
>>> g(2, z=4, y=5)
#关键参数
11
>>> L = [(lambda x: x**2),(lambda x: x**3),(lambda: 2**4)]
>>> print(L[0](2),L[1](2),L[2]())
4 8 16
>>> D = {'f1':(lambda:2+3),'f2':(lambda:2*3), f3':(lambda:2**3)}
>>> print(D['f1'](), D['f2'](), D['f3']())
5 6 8
>>> L = [1,2,3,4,5]
>>> print(list(map(lambda x: x+10, L))) #模拟向量运算
[11, 12, 13, 14, 15]
>>> L
[
1, 2
, 3
, 4, 5]
lambda表
达
式3
35
5
lambda表达式的分析
>>> data = list(range(20))
#创建列表
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> import random
>>> random.shuffle(data)
#打乱顺序
>>> data
[4, 3, 11, 13, 12, 15, 9, 2, 10, 6, 19, 18, 14, 8, 0, 7, 5, 17, 1, 16]
>>> data.sort(key=lambda x: x) #和不指定规则效果一样
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> data.sort(key=lambda x: len(str(x))) #按转换字符串长度排序
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> data.sort(key=lambda x: len(str(x)), reverse=True)#降序排序
>>> data
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lambda表达式3
36
6
函数应用案例-1
l 编写函数计算圆的面积【
03P36-1.py】
from math import pi as PI
def CircleArea(r):
if isinstance(r, (int, float)): #确保接收的参数为数值
return PI*r*r
else:
print('You must give me an integer or float as radius.')
print(CircleArea(3))
l 编写函数接收任意多个实数,返回元组,其中首元素
为平均值,其它元素依次为所有大于平均值的参数
【
03P36-2.py】
def demo(*para):
avg = sum(para) / len(para) #平均值
g = [i for i in para if i>avg] #列表推导式
#g=(i for i in para if i>avg) #生成器推导式
return (avg,)+tuple(g)
print(demo(1, 2, 3, 4))
函数程序案例37
3
7
函数应用案例-2
l 编写函数接收字符串参数,返回元组,其中第一个元
素为大写字母个数,第二个元素为小写字母个数
【
03P37.py】
def demo(s):
result=[0, 0]
for ch in s:
result[1] += ('a'<=ch<='z')
result[0] += ('A'<=ch<='Z')
return tuple(result)
l 编写函数接收整数参数t,返回斐波那契数列中大于t
的第一个数
def demo(t):
a, b = 1, 1
while b < t:
a, b = b, a+b
else:
return b
函数程序案例3
38
8
函数应用案例-3
l 编写函数接收包含20个整数的列表lst和整数k,返回
列表。处理规则为:将列表lst中下标k之前的元素逆
序,下标k及之后的元素逆序,然后将整个列表lst中
的所有元素逆序【
03P38.py】
def demo(lst, k):
x=lst[:k]
x.reverse()
lst[:k]=x
#注意切片操作是浅复制
x=lst[k:]
x.reverse()
lst[k:]=x
lst.reverse()
return lst
lst = list(range(1, 21))
print(lst)
print(demo(lst, 5))
函数程序案例3
9
39
函数应用案例-4
l 编写函数,接收包含若干整数的列表lst,返回元组,
其中首元素为列表lst中的最小值,其余元素为最小值
在列表lst中的下标【
03P39.py】
import random
def demo(lst):
m = min(lst)
result = (m,)
positions = [index for index, value in enumerate(lst) if value==m]
result = result + tuple(positions)
return result
x = [random.randint(1, 20) for i in range(50)]
print(x)
print(demo(x))
函数程序案例4
0
40
函数应用案例-5
l 编写函数打印杨辉三角前t行【
03P40-1.py】
def demo(t):
result = [[1], [1, 1]]
line = [1, 1]
for i in range(2, t):
r = []
for j in range(0, len(line)-1):
r.append(line[j]+line[j+1])
line = [1]+r+[1]
result.append(line)
return result
def output(result):
for item in result:
print(item)
函数程序案例
简洁思路【
03P40-2.py】:
def f(n):
x=[]
for i in range(n):
y
=
[
1
]
fo
r
j
in range(i):
y.append(x[j]+x[j+1])
y.append(1)
print(y)
x=y4
1
4
1
函数应用案例-6
l 哥德巴赫猜想验证:函数接收正偶数为参数,输出全
部满足和等于正偶数参数的素数对【
03P41.py】
import math
def IsPrime(n):
m = int(math.sqrt(n))+1
for i in range(2, m):
if n%i==0:
return False
return True
def demo(n):
if isinstance(n, int) and n>0 and n%2==0:
for i in range(3, int(n/2)+1):
if i%2==1 and IsPrime(i) and IsPrime(n-i):
print(i, '+', n-i, '=', n)
demo(60)
函数程序案例4
2
4
2
函数应用案例-7
l 编写函数接收两个正整数,返回元组,其中首元素为
最大公约数,第二个元素为最小公倍数【
03P42.py】
def demo(m, n):
#辗转相除法
if m>n:
m, n = n, m
p = m*n
while m!=0:
r = n%m
n = m
m = r
return (n, int(p/n))
l Python标准库fractions中提供了gcd()函数用来计算最
大公约数,在Python 3.5之后的版本中,标准库math
也提供了计算最大公约数的gcd()
def demo(m, n):
import math
r = math.gcd(m,n)
r
etu
rn (r, int(m*n/r))
函数程
序
案
例4
3
43
函数应用案例-8
l 模拟发红包【
03P43.py】
import random
def hongbao(total, num):#全局total为红包总额,全局num表示红
包数
each = []
already = 0#已发红包总金额
for i in range(1, num):
t = random.randint(1, (total-already)-(num-i))
#为当前人随机分配金额,至少给剩下的人每人留一分钱
each.append(t)
already = already+t
each.append(total-already) #剩余所有钱发给最后一个人
return each
if __name__=='__main__':
total = 5
num = 5
for i in range(30): #模拟30次
e
ach = hongbao(total, num)
print(each)
函数程
序
案
例
不使用全局怎么实现?4
4
44
函数应用案例-9
l 计算形式如a+aa+aaa+aaaa+...+aaa...aaa的表达式的值,
其中a为小于10的自然数【
03P44.py】
def demo(v, n):
assert 0<v<10, 'v must between 1 and 9'
assert type(n)==int, 'n must be integer'
result, t = 0, 0
for i in range(n):
t = t*10 + v
result += t
return result
print(demo(3, 4))
函数程序案例45
4
5
函数应用案例-10
l 汉诺塔问题【
03P45.py】
def hannuo(num, src, dst, temp=None):
global times#全局times记录移动次数
#确认参数类型和范围
assert type(num) == int, 'num must be integer'
assert num >=0, 'num must > 0'
if num > 0:#递归结束条件,已优化
hannuo(num-1, src, temp, dst)
print('The {0} Times move:{1}==>{2}'.format(times, src, dst)
#移动最大圆盘到目标柱子上
times += 1
hannuo(num-1, temp, dst, src)
times = 1
hannuo(5, 'A', 'C', 'B') #A原柱,C目标柱,B临时柱

浙公网安备 33010602011771号