2018.7.16
day10回顾:
局部变量 全局变量
locals() globals()
def fa(a, b):
pass
一个函数可以作为参数传入另一个函数
def fx(fn):
pass
fx(max) # 传入一个函数
函数可以作为另一个函数的返回值
def fx():
return max
m = fx() # 此函数调用返回一个max函数
def fy():
def hello():
print("hello")
return hello
h = fy()
h() # 此
函数嵌套定义
python 四个作用域:
局部作用域
外部嵌套函数作用域
全局作用域
内建模块的作用域
global 语句
nonlocal 语句
def 语句创建函数
lambda 表达式
myadd = lambda x, y: x + y
eval(s) 函数
... 表达式 ...
exec(s) 函数
... 语句(程序) ...
day11笔记:
函数式编程
函数式编程是指用一系列函数解决问题
好处:
1. 用每一个函数完成细小的功能,一系列函数的任意组合可以完成大问题
2. 函数仅接受输入并产生输入,不包含任何能影响输出的内部状态
函数的可重入性
如果一个函数的输入参数一定,则返回结果必须一定的函数称为可重入函数
示例:
# 可重入函数,传入参数一定.结果必然一定
def myadd(x, y):
return x + y
# 不可重入函数:
y = 200
def myadd2(x):
return x + y
print(myadd2(10)) # 210
y = 300
print(myadd2(10)) # 310
函数式编程的要求:
def 创建的函数最好不要访问局部作用域以外的变量,这样可以保证返回结果的唯一性(可重入性)
高阶函数 High Order Function
什么是高阶函数:
满足下列条件之一的即为高阶函数
1. 函数接受一个或多个函数作为参数传入
2. 函数返回一个函数
python内建的高阶函数:
map, filter, sorted
详见:
python_base_docs_html/内建函数(builtins).html
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 ....
print('---------------------')
# 生成 1**3 , 2**3, 3**3
def power3(x):
return x ** 3
for x in map(power3, range(1, 10)):
print(x)
print('======================')
for x in map(lambda x: x**4, range(1, 10)):
print(x)
练习:
1. 用map函数求:
1**3 + 2**3 + 3 ** 3 + .... 9**3 的和
# 1. 用map函数求:
# 1**3 + 2**3 + 3 ** 3 + .... 9**3 的和
s = 0
# 方法1
# for x in range(1, 10):
# s += x ** 3
#方法2
# for x in map(lambda x: x**3, range(1, 10)):
# s += x
# 方法3
s = sum(map(lambda x: x**3, range(1, 10)))
print('和是:', s)
2. 用map函数求:
1**4 + 2**4 + 3 ** 4 + .... 20**4 的和
# 2. 用map函数求:
# 1**4 + 2**4 + 3 ** 4 + .... 20**4 的和
s = sum(map(lambda x: x**4, range(1, 21)))
print('和是:', s)
map示例:
求 1**9 + 2**8 + 3**7 + ...... 9**1
s = 0
for x in map(pow, range(1, 10), range(9, 0,-1)):
s += x
print(s)
filter 函数:
filter(function, iterable)
filter示例见:
# 写一个函数判断x是否为奇数,奇数返回True,偶数返回False
def is_odd(x):
if x % 2 == 1:
return True
return False
# 生成1~10以内奇数的列表 # [1, 3, 5, 7, 9]
for x in filter(is_odd, range(1, 10)):
print(x)
L = [x for x in filter(is_odd, range(1, 10))]
print(L) # [1, 3, 5, 7, 9]
练习:
1. 将 1 ~ 20 的偶数用filter生成可迭代对象后将可迭代对象生成的数放入到列表L中
def is_even(x): # 判断x是否是偶数
if x % 2 == 0:
return True
return False
evens = filter(is_even, range(1, 21))
# L = list(evens)
L = [x for x in evens]
print(L)
2. 写一个函数is_prime(x) 判断x是否是素数
用filter函数打印出: 20 ~ 30之间的全部素数
def is_prime(x):
if x < 2:
return False
# 排序法
for i in range(2, x):
if x % i == 0:
return False
return True
for x in filter(is_prime, range(20, 30)):
print(x)
sorted 函数:
作用:
将原可迭代对象的数据进行排序,生成排序后的列表
格式:
sorted(iterable, key=None, reverse=False)
说明:
iterable 可迭代对象
key 函数是用来提供一个值,这个值将做为排序的依据
reverse 标志用来设置是否降序排序
示例见:
L = [5, -2, -4, 0, 3, 1]
L2 = sorted(L) # L = [-4, -2, 0, 1, 3, 5]
L3 = sorted(L, reverse=True) # 降序排序
L4 = sorted(L, key=abs) # L4 = [0, 1, -2, 3, -4, 5]
print(L4)
L5 = sorted(L, key=abs, reverse=True) # L5 = [5, -4, 3, -2, 1, 0]
print("L5=", L5)
练习:
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
排序的依据为字符串的反序:
'moT' yrreJ ekipS ekyT
结果:
['Spike', 'Tyke', 'Tom', 'Jerry']
names = ['Tom', 'Jerry', 'Spike', 'Tyke']
def k(s):
print("k()传入:", s, "返回去的", s[::-1])
return s[::-1]
L = sorted(names, key=k)
print(L) # ['Spike', 'Tyke', 'Tom', 'Jerry']
递归函数 recursion
函数直接或间接的调用自身
递归示例:
# 函数直接调用自己
def f():
f() # 调用自己
f()
# 函数间接的调用自己
def fa():
fb()
def fb():
fa()
fa()
递归说明:
递归一定要控制递归的层数,当符合一定条件时要终止递归
几乎所有的递归都能用while循环来代替
递归的优缺点:
优点:
递归把问题简单化,让思路更为清晰,代码更简洁
缺点:
递归因系统环境影响大,当递归深度太大时,可能会得到不可预知的结果
递归的两个阶段
递推阶段: 从原问题出发,按递归公式递推从末知到已经,最终达到递归的终止条件
回归阶段: 按递归终止条件求出结果,逆向逐步代入递归公式.回归到原问题求解
示例见:
def fx(n):
print("fx进入第", n, '层')
if n == 3:
return
fx(n + 1)
print("fx退出第", n, '层')
fx(1)
print("程序结束")
# n! = 1 * 2 * 3 * 4 * ..... * n
# n! = n * (n-1) * (n-2) * ..... 3 * 2 * 1
# 100! = 100 * 99 * 98 * ..... 3 * 2 * 1
def fac(n):
# 此函数用递归的方式实现阶乘
if n == 1: # 1! 直接返回1
return 1
return n * fac(n - 1)
print(fac(5)) # 120
练习:
写函数 mysum(n)用递归方式实现求和
def mysum(n):
if n == 0:
return 0
return n + mysum(n - 1)
print(mysum(100)) # 5050
思考题:
已知五位朋友在一起
第五位朋友比第四位朋友大2岁
第四位朋友比第三位朋友大2岁
第三位朋友比第二位朋友大2岁
第二位朋友比第一位朋友大2岁
第一位朋友说它10岁
闭包 closure
什么是闭包:
闭包是指引用了此函数外部的变量的函数
说明:
在本质上,闭包是将内部嵌套函数和函数外部的执行环境绑定在一起的对象
闭包必须满足三个条件:
1. 必须有一个内嵌函数
2. 内嵌函数必须引用外部函数中的变量
3. 外部函数返回值必须是内嵌函数
示例见:
# 闭包示例:
def make_power(y):
def fn(arg):
return arg ** y
return fn
pow2 = make_power(2) # 请问pow2绑定的是什么?
print('5的平方是:', pow2(5))
# 求1**2 + 2 ** 2 + 3 ** 2 + .... 100 ** 2
print(sum(map(lambda x: x ** 2, range(1, 101))))
print(sum(map(make_power(2), range(1, 101))))
print("1 ** 3 + 2**3 + ...... + 100 ** 3=")
print(sum(map(lambda x: x ** 3, range(1, 101))))
print(sum(map(make_power(3), range(1, 101))))
# print(sum(map(lambda x: x ** 3, range(1, 101))))
闭包的应用见:
# 用闭包来创建函数:
# f(x) = a**x**2 + b*x + c
def get_fx(a, b, c):
def fx(x):
return a * x ** 2 + b * x + c
return fx
f123 = get_fx(1, 2, 3)
print(f123(20))
print(f123(50))
f654 = get_fx(6,5,4)
print(f654(10))
print(f654(30))
练习:
1. 已知五位朋友在一起
第五位朋友比第四位朋友大2岁
第四位朋友比第三位朋友大2岁
第三位朋友比第二位朋友大2岁
第二位朋友比第一位朋友大2岁
第一位朋友说它10岁
写程序打印出第五位朋友 和第三位朋友 的年龄
def get_age(n):
if n == 1:
return 10
return get_age(n - 1) + 2
print("第五位朋友%d岁" % get_age(5))
print("第三位朋友%d岁" % get_age(3))
2. 已知有列表:
L = [[3, 5, 8], 10, [[13, 14], 15, 18], 20]
1) 写一个函数print_list(lst) 打印出所有元素
print(L) # 打印 3 5 8 10 13 14 ....
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], 20]
# 1) 写一个函数print_list(lst) 打印出所有元素
def print_list(lst):
for x in lst:
if type(x) is list: # 如果x是列表,则再次再印
print_list(x)
else:
print(x)
print_list(L) # 打印 3 5 8 10 13 14 ....
# 2) 写一个函数sum_list(lst) 返回这个列表中所有元素的和
def sum_list(lst):
s = 0
for x in lst:
if type(x) is list: # 是列表
s += sum_list(x)
else: # 不是列表
s += x
return s
print(sum_list(L)) # 106
3. 改写之前的学生信息管理程序
要求添加四个功能:
| 5) 按学生成绩高-低显示学生信息 |
| 6) 按学生成绩低-高显示学生信息 |
| 7) 按学生年龄高-低显示学生信息 |
| 8) 按学生年龄低-高显示学生信息 |
def input_student():
L = [] # 创建一个容器准备放入
while True:
name = input('请输入姓名: ')
if not name: # 如果名字为空,结束输入操作
break
age = int(input("请输入年龄: "))
score = int(input("请输入成绩: "))
d = {} # 每次都会执行{} 来创建新的字典
d['name'] = name
d['age'] = age
d['score'] = score
L.append(d)
return L
def output_student(lst):
# 打印表格
print("+---------------+----------+----------+")
print("| name | age | score |")
print("+---------------+----------+----------+")
for d in lst:
n = d['name'].center(15)
a = str(d['age']).center(10)
s = str(d['score']).center(10)
print("|%s|%s|%s|" % (n, a, s))
print("+---------------+----------+----------+")
def output_student_by_score_desc(lst):
def k(d):
return d['score']
L = sorted(lst, key=k, reverse=True)
output_student(L)
def output_student_by_score_asc(lst):
L = sorted(lst, key=lambda d: d['score'])
output_student(L)
def output_student_by_age_desc(lst):
L = sorted(lst, key=lambda d: d['age'],
reverse=True)
output_student(L)
def output_student_by_age_asc(lst):
L = sorted(lst, key=lambda d: d['age'])
output_student(L)
def show_menu():
print('+----------------------------------+')
print('| 1) 添加学生信息 |')
print('| 2) 显示学生信息 |')
print('| 3) 删除学生信息 |')
print('| 4) 修改学生成绩 |')
print('| 5) 按学生成绩高-低显示学生信息 |')
print('| 6) 按学生成绩低-高显示学生信息 |')
print('| 7) 按学生年龄高-低显示学生信息 |')
print('| 8) 按学生年龄低-高显示学生信息 |')
print('| q) 退出 |')
print('+----------------------------------+')
def main():
docs = [] # 用于存放学生信息的空列表
while True:
show_menu()
s = input("请选择: ")
if s == '1':
docs += input_student()
elif s == '2':
output_student(docs)
elif s == '3':
print("开始删除")
elif s == '4':
print("开始修改成绩")
elif s == '5':
output_student_by_score_desc(docs)
elif s == '6':
output_student_by_score_asc(docs)
elif s == '7':
output_student_by_age_desc(docs)
elif s == '8':
output_student_by_age_asc(docs)
elif s == 'q':
break
main()