day11回顾:
变量
局部变量
全局变量
变量
局部变量
全局变量
globals() / locals()
用来获取全局变量和局部变量的字典
用来获取全局变量和局部变量的字典
函数名是变量
def xxx(....):
pass
pass
一个函数可以作为实参传入另一个函数
def fx(fn, L):
pass
fx(max, [1,2,3])
def fx(fn, L):
pass
fx(max, [1,2,3])
函数可以作为另一个函数的返回值
def fx():
def hello():
print("hello world")
return hello
fh = fx()
fh() # 调用hello这个函数
def fx():
def hello():
print("hello world")
return hello
fh = fx()
fh() # 调用hello这个函数
python 的四个作用域:
L E G B
局部 外部嵌套函数作用域 全局 内建作用域
L E G B
局部 外部嵌套函数作用域 全局 内建作用域
global 语句
nonlocal 语句
nonlocal 语句
day12笔记:
lambda 表达式(又名匿名函数表达式)
作用:
创建一个匿名函数对象
同def类似,但不提供函数名
语法:
lambda [形参1, 形参2, ...] : 表达式
作用:
创建一个匿名函数对象
同def类似,但不提供函数名
语法:
lambda [形参1, 形参2, ...] : 表达式
示例:
def myadd(x, y):
return x + y
可以改写为:
myadd = lambda x, y: x + y
print(myadd(100, 200))
print(myadd("ABC", "100"))
def myadd(x, y):
return x + y
可以改写为:
myadd = lambda x, y: x + y
print(myadd(100, 200))
print(myadd("ABC", "100"))
语法说明:
1. lambda 只是一个表达式,它用来创建一个函数对象
2. 当lambda表达式调用时,先执行冒号后的表达式,并返回表达式的结果的引用
3. lambda 表达式创建的函数只能包含一条表达式
4. lambda比函数简单,且可以随时创建和销毁,有利于减少程序的偶合度
1. lambda 只是一个表达式,它用来创建一个函数对象
2. 当lambda表达式调用时,先执行冒号后的表达式,并返回表达式的结果的引用
3. lambda 表达式创建的函数只能包含一条表达式
4. lambda比函数简单,且可以随时创建和销毁,有利于减少程序的偶合度
练习:
1. 写一个lambda表达式, 判断这个数的2次方+1 能否被5整数,如果能整除返回True, 否则返回False
fx = lambda n: .......
print(fx(4)) # False
print(fx(3)) # True
2. 写一个lambda 表达式,求两个变量的最大值:
mymax = lambda ...
print(mymax(55, 63)) # 63
1. 写一个lambda表达式, 判断这个数的2次方+1 能否被5整数,如果能整除返回True, 否则返回False
fx = lambda n: .......
print(fx(4)) # False
print(fx(3)) # True
2. 写一个lambda 表达式,求两个变量的最大值:
mymax = lambda ...
print(mymax(55, 63)) # 63
看懂下面的程序在做什么:
def fx(f, x, y):
r = f(x, y)
print(r)
fx((lambda a, b: a + b), 100, 200)
fx((lambda x, y: x ** y), 3, 4)
def fx(f, x, y):
r = f(x, y)
print(r)
fx((lambda a, b: a + b), 100, 200)
fx((lambda x, y: x ** y), 3, 4)
eval 和 exec 函数
eval函数:
作用:
把一个字符串当成一个表达式执行,返回表达式执行后的结果
格式:
eval(source, globals=None, locals=None)
示例:
x = 100
y = 200
s = "x+y"
v = eval(s)
print(a)
eval函数:
作用:
把一个字符串当成一个表达式执行,返回表达式执行后的结果
格式:
eval(source, globals=None, locals=None)
示例:
x = 100
y = 200
s = "x+y"
v = eval(s)
print(a)
print(eval("x+y", {'x':10, 'y':20})) # 30
print(eval("x+y", {'x':10, 'y':20}, {'x':1, 'y':2})) # 3
print(eval("x+y", {'x':10, 'y':20}, {'x':1})) # 21
print(eval("x+y", {'x':10, 'y':20}, {'x':1, 'y':2})) # 3
print(eval("x+y", {'x':10, 'y':20}, {'x':1})) # 21
exec函数:
作用:
把一个字符串当成程序来执行
格式:
exec(source, globals=None, local=None)
示例:
s = 'x=100; print("hello"); x += 1; print(x)'
print(s)
exec(s)
作用:
把一个字符串当成程序来执行
格式:
exec(source, globals=None, local=None)
示例:
s = 'x=100; print("hello"); x += 1; print(x)'
print(s)
exec(s)
示例:
自己写一个程序,解释执行用户输入的任何语句:
见: myprog.py
自己写一个程序,解释执行用户输入的任何语句:
见: myprog.py
函数式编程:
是指用一系列函数解决问题
是指用一系列函数解决问题
函数是一等公民
1. 函数本身是对象,可以赋值给变量,赋值后变量绑定函数
2. 允许将函数作为实参传入另一个函数
3. 允许函数返回一个函数
1. 函数本身是对象,可以赋值给变量,赋值后变量绑定函数
2. 允许将函数作为实参传入另一个函数
3. 允许函数返回一个函数
函数式编程的好处:
1. 每一个函数完成细小的功能,一系列函数的任意组合可以解决大的问题
2. 函数仅接收输入并产生输入,不会影响其它全局变量的状态
1. 每一个函数完成细小的功能,一系列函数的任意组合可以解决大的问题
2. 函数仅接收输入并产生输入,不会影响其它全局变量的状态
思考:
求 1+ 2 + 3 + ...... + n 的和
print(sum(range(n+1)))
求 1+ 2 + 3 + ...... + n 的和
print(sum(range(n+1)))
练习:
求: 1 + 1/2 + 1/4 + 1/8 + ... + 1/2**n
n = 100
print(sum([1/2**x for x in range(n + 1)]))
求: 1 + 1/2 + 1/4 + 1/8 + ... + 1/2**n
n = 100
print(sum([1/2**x for x in range(n + 1)]))
高阶函数 High Order Function
什么是高阶函数:
满足下列条件中的一个的函数即为高阶函数
1. 函数接受一个或多个函数作为参数传入
2. 函数返回一个函数
什么是高阶函数:
满足下列条件中的一个的函数即为高阶函数
1. 函数接受一个或多个函数作为参数传入
2. 函数返回一个函数
python内置(builtins)的高阶函数:
map, filter, sorted
map 函数:
map(func, *iterables) 用函数对可迭代对象中的每一个元素作为参数计算出新的可迭代对象,当最短的一个可迭代对象不再提供数据时,此可迭代对象生成结束
map, filter, sorted
map 函数:
map(func, *iterables) 用函数对可迭代对象中的每一个元素作为参数计算出新的可迭代对象,当最短的一个可迭代对象不再提供数据时,此可迭代对象生成结束
示例 :
# 生成一个可迭代对象,要求此可迭代对象可以生成1~9自然数的平方
1, 4, 9, 16, .... 81
def power2(x):
return x**2
for x in map(power2, range(1, 10)):
print(x)
# 求以上数据的和 1 + 4 + 9 + 16 + ... + 81
print(sum(map(power2, range(1, 10))))
# 生成一个可迭代对象,要求此可迭代对象可以生成1~9自然数的平方
1, 4, 9, 16, .... 81
def power2(x):
return x**2
for x in map(power2, range(1, 10)):
print(x)
# 求以上数据的和 1 + 4 + 9 + 16 + ... + 81
print(sum(map(power2, range(1, 10))))
示例:
# 生成一个可迭代对象, 要求此可迭代对象生成
# 1**4, 2**3, 3**2, 4**1
# 1 8 9 4
for x in map(pow, [1,2,3,4], [4,3,2,1]):
print(x)
练习:
1. 求 1**2 + 2**2 + 3**2 + ... 9**2的和
def f2(x):
return x ** 2
s = sum(map(f2, range(1, 10)))
print(s)
# 方法2
print(sum(map(lambda x: x**2, range(1, 10))))
# 生成一个可迭代对象, 要求此可迭代对象生成
# 1**4, 2**3, 3**2, 4**1
# 1 8 9 4
for x in map(pow, [1,2,3,4], [4,3,2,1]):
print(x)
练习:
1. 求 1**2 + 2**2 + 3**2 + ... 9**2的和
def f2(x):
return x ** 2
s = sum(map(f2, range(1, 10)))
print(s)
# 方法2
print(sum(map(lambda x: x**2, range(1, 10))))
2. 求 1**3 + 2**3 + 3**3 + ... 9**3的和
print(sum(map(lambda x: x**3, range(1, 10))))
3. 求 1**9 + 2**8 + 3**7 + ... 9**1的和
print(sum(map(pow, range(1, 10), range(9, 0, -1))))
print(sum(map(lambda x: x**3, range(1, 10))))
3. 求 1**9 + 2**8 + 3**7 + ... 9**1的和
print(sum(map(pow, range(1, 10), range(9, 0, -1))))
filter函数:
格式:
filter(func, iterable)
作用:
筛选可迭代对象iterable中的数据,返回一个可迭代对象,此可迭代对象将对iterable进行筛选
函数func 将对iterable中的每个元素进行求值,返回False时将此数据丢弃,返回True,则保留此数据
格式:
filter(func, iterable)
作用:
筛选可迭代对象iterable中的数据,返回一个可迭代对象,此可迭代对象将对iterable进行筛选
函数func 将对iterable中的每个元素进行求值,返回False时将此数据丢弃,返回True,则保留此数据
示例:
# isodd函数判断x是否为奇数,是奇数返回True
def isodd(x):
return x % 2 == 1
# isodd函数判断x是否为奇数,是奇数返回True
def isodd(x):
return x % 2 == 1
# 打印10以内的奇数:
for x in filter(isodd, range(10)):
print(x)
for x in filter(isodd, range(10)):
print(x)
# 生成10以内所有偶数的列表,用filter实现
L = [x for x in filter(lambda x: x%2==0, range(10))]
L = [x for x in filter(lambda x: x%2==0, range(10))]
sorted 函数:
作用:
将原可迭代对象的数据进行排序,生成排序后的列表
格式:
sorted(iterable, key=None, reverse=False)
参数说明:
iterable 可迭代对象
key 绑定函数,此函数用来提供一个排序的依据
reverse 标志用来设置是否降序排序(从大到小)
示例:
L = [5, -2, -4, 0, 3, 1]
L2 = sorted(L) # L2 = [-4, -2, 0, 1, 3, 5]
L3 = sorted(L, reverse=True) L3=[5,3,1...]
作用:
将原可迭代对象的数据进行排序,生成排序后的列表
格式:
sorted(iterable, key=None, reverse=False)
参数说明:
iterable 可迭代对象
key 绑定函数,此函数用来提供一个排序的依据
reverse 标志用来设置是否降序排序(从大到小)
示例:
L = [5, -2, -4, 0, 3, 1]
L2 = sorted(L) # L2 = [-4, -2, 0, 1, 3, 5]
L3 = sorted(L, reverse=True) L3=[5,3,1...]
L = [5, -2, -4, 0, 3, 1]
# 依据: abs(5), abs(-2), abs(-4), abs(0), ...
L4 = sorted(L, key=abs) # L4 =[0, 1, -2, 3, -4, 5]
# 依据: abs(5), abs(-2), abs(-4), abs(0), ...
L4 = sorted(L, key=abs) # L4 =[0, 1, -2, 3, -4, 5]
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
L = sorted(names) # L = ['Jerry', 'Spike', 'Tom', 'Tyke']
# 能否根据名字的长度进行排序?
L2 = sorted(names, key=len) # L2 = ['Tom', 'Tyke', 'Jerry', 'Spike']
L = sorted(names) # L = ['Jerry', 'Spike', 'Tom', 'Tyke']
# 能否根据名字的长度进行排序?
L2 = sorted(names, key=len) # L2 = ['Tom', 'Tyke', 'Jerry', 'Spike']
def fr(s):
return s[::-1]
L3 = sorted(names, key=fr)
return s[::-1]
L3 = sorted(names, key=fr)
递归函数 recursion
函数直接或间接的调用自身
函数直接或间接的调用自身
示例:
# 直接调用自身
def f():
f() # 调用自己
f()
print("递归完成")
# 直接调用自身
def f():
f() # 调用自己
f()
print("递归完成")
# 函数间接调用自身
def fa():
fb()
def fa():
fb()
def fb():
fa()
fa()
fa()
fa()
递归说明:
递归一定要控制递归的层数,当符合某一条件时要终止递归
几乎所有的递归都能用循环来代替
递归一定要控制递归的层数,当符合某一条件时要终止递归
几乎所有的递归都能用循环来代替
递归的优缺点:
优点:
递归可以把问题简单化,让路径更为清晰,代码更为简洁
缺点:
递归因系统环境影响大,当递归深度太大时,可以会得到不可预知的结果
优点:
递归可以把问题简单化,让路径更为清晰,代码更为简洁
缺点:
递归因系统环境影响大,当递归深度太大时,可以会得到不可预知的结果
示例:
def story():
print("从前有座山,山上有座庙,庙里有个老和尚讲故事: ")
stroy()
print("故事请讲完了")
def story():
print("从前有座山,山上有座庙,庙里有个老和尚讲故事: ")
stroy()
print("故事请讲完了")
递归函数的实现方法:
先假设函数已经实现
先假设函数已经实现
示例:
求:100 + 99 + 98 + 97 + ..... + 1 的和
分析:
先假设 mysum(x) 已经完成,且能求
x + (x-1) + .. +1的和
def mysum(x):
# 选判断终止条件
if x == 1:
return 1
return x + mysum(x - 1)
求:100 + 99 + 98 + 97 + ..... + 1 的和
分析:
先假设 mysum(x) 已经完成,且能求
x + (x-1) + .. +1的和
def mysum(x):
# 选判断终止条件
if x == 1:
return 1
return x + mysum(x - 1)
print(mysum(100)) # 5050
练习:
1. 编写函数 myfac(x) 计算x的阶乘x!
5! = 5 * 4 * 3 * 2 * 1
1. 编写函数 myfac(x) 计算x的阶乘x!
5! = 5 * 4 * 3 * 2 * 1
print(myfac(5)) # 120
2. 写程序算出1~20的阶乘的和
1! + 2! + 3! + .... + 19! + 20!
思考:
能否用函数式编程中的高阶函数实现?
2. 写程序算出1~20的阶乘的和
1! + 2! + 3! + .... + 19! + 20!
思考:
能否用函数式编程中的高阶函数实现?
3. 已知有列表:
L = [[3,5,8], 10, [[13, 14], 15], 18]
1) 写一个函数 print_list(lst) 打印出列表中所有数字
print_list(L)
2) 写一个函数sum_list(lst) 返回列表中所有数字的和
print(sum_list(L)) # 86
注:
type(x) 可以返回一个变量的类型
如:
>>> type(20) is int # True
>>> type([1,2,3]) is list # True
L = [[3,5,8], 10, [[13, 14], 15], 18]
1) 写一个函数 print_list(lst) 打印出列表中所有数字
print_list(L)
2) 写一个函数sum_list(lst) 返回列表中所有数字的和
print(sum_list(L)) # 86
注:
type(x) 可以返回一个变量的类型
如:
>>> type(20) is int # True
>>> type([1,2,3]) is list # True
4. 开始学生信息管理项目
需要两个函数:
input_student() 返回学生信息的字典的列表
output_student(lst) 以表格式方打印学生信息
学生信息:
姓名(name) 字符串
年龄(age) 整数
成绩(score) 整数
需要两个函数:
input_student() 返回学生信息的字典的列表
output_student(lst) 以表格式方打印学生信息
学生信息:
姓名(name) 字符串
年龄(age) 整数
成绩(score) 整数
input_student() 调用时等待用户输入学生信息,当输入姓名为空时结束输入,最后将学生信息形成字典后存如列表中返回
def input_student():
....
def input_student():
....
L = input_student()
请输入学生姓名: xiaozhang
请输入学生年龄: 20
请输入学生成绩: 98
请输入学生姓名: xiaoli
请输入学生年龄: 23
请输入学生成绩: 100
请输入学生姓名: <回车>输入结束
此时列表数据为:
L = [{'name':'xiaozhang',
'age':20,
'score': 98},
{'name':'xiaoli',
'age':23,
'score': 100}
]
def output_student(lst):
...
请输入学生姓名: xiaozhang
请输入学生年龄: 20
请输入学生成绩: 98
请输入学生姓名: xiaoli
请输入学生年龄: 23
请输入学生成绩: 100
请输入学生姓名: <回车>输入结束
此时列表数据为:
L = [{'name':'xiaozhang',
'age':20,
'score': 98},
{'name':'xiaoli',
'age':23,
'score': 100}
]
def output_student(lst):
...
print(L) # 打印出字典的列表
output_student(L) # 打印出学生信息的表格如下:
+-----------+--------+---------+
| name | age | score |
+-----------+--------+---------+
| xiaozhang | 20 | 98 |
| xiaoli | 23 | 100 |
+-----------+--------+---------+
output_student(L) # 打印出学生信息的表格如下:
+-----------+--------+---------+
| name | age | score |
+-----------+--------+---------+
| xiaozhang | 20 | 98 |
| xiaoli | 23 | 100 |
+-----------+--------+---------+