python求和函数1-n_PYTHON1.day11(n)

day10回顾

函数名是变量,它用来绑定"函数"

函数可以作为参数传入另一个函数

函数可以返回另一个函数

函数的嵌套定义

def f1():

def f2():

pass

f2()

四个作用域:

局部作用域

外部嵌套函数作用域

全局作用域

内建作用域

LEGB

global 语句

nonlocal 语句

lambda 表达式

作用:

创建简单的匿名函数

语法:

lambda 形参列表: 表达式

等同于:

def xxxx(形参列表):

return 表达式

eval(字符串, globals=None, locals=None) 函数

exec(字符串, globals=None, locals=None) 函数

day11 笔记:

函数式编程 Functional Programming

函数式编程是指用一系列函数解决问题

好处:

用每一个函数完全细小的功能,一系列函数的任意组合可以完成大问题

函数仅接受输入并产生输出,不包含任何能影响输出的内部状态

函数的可重入性

当一个函数没有访问除局部变量以外的变量,则此函数为可重入函数

说明:

可重入函数输入一定.结果必然一定

示例:

# 可重入函数:

def myadd1(x, y):

return x + y

# 不可重入函数

s = 0

def myadd2(x, y):

global s

s += x + y

return s

高阶函数 High Order Function

什么是高阶函数:

满足下列条件中的一个的函数即为高阶函数

1. 函数接收一个或多个函数作为参数传入

2. 函数返回一个函数

python 内置的高阶函数:

map, filter, sorted

map 函数

参数格式:

map(func, iterable, ...)

参数:

func 对可迭代对象的数据进行处理的函数,函数的参数必须

与可迭代对象的个数相同

iterable, 一个或多个可迭代对象,用来给map提供数据

返回值:

可迭代对象

示例见:

map.py

map2.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # map.py

2

3

4 # 此示例示意map的用法

5 def power2(x):

6 print("power2被调用! x=", x)

7 return x ** 2

8

9 # 生成一个可迭代对象,此可迭代对象可以生成1~9自然数的平方

10 # 1 4 9 16 25 36 .... 81

11

12 for x in map(power2, range(1, 10)):

13 print(x) # 1, 4, 9, 16, 25, ...

14

15 # 求:

16 # 1 + 4 + 9 + 16 + .... + 81的和

17 print(sum(map(power2, range(1, 10))))

18map.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # map2.py

2

3 # 生成一个可迭代对象,此可迭代对象可以生成

4 # 1**4, 2**3, 3**2, 4**1

5 # pow(x, y, z=None) 内建函数

6

7

8 for x in map(pow, [1, 2, 3, 4], [4, 3, 2, 1]):

9 print(x) # 1, 8, 9, 4

10

11 print('-----------')

12 for x in map(pow, [1,2,3,4],

13 [4, 3, 2, 1, 0],

14 range(5, 10)):

15 print(x) # 1, 2, 2, 4

16

17map2.py

练习:

1. 求:

1**2 + 2**2 + 3**2 + .... + 9**2的和

2. 求:

1**3 + 2**3 + 3**3 + .... + 9**3的和

3. 求:

1**9 + 2**8 + 3**7 + .... + 9**1的和

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 练习:

2 # 1. 求:

3 # 1**2 + 2**2 + 3**2 + .... + 9**2的和

4 # 2. 求:

5 # 1**3 + 2**3 + 3**3 + .... + 9**3的和

6 # 3. 求:

7 # 1**9 + 2**8 + 3**7 + .... + 9**1的和

8

9

10

11 # 1. 求:

12 # 1**2 + 2**2 + 3**2 + .... + 9**2的和

13 # 方法1

14 # def power2(x):

15 # return x ** 2

16 # print(sum(map(power2, range(1, 10))))

17

18 # 方法2

19 print(sum(map(lambda x: x**2, range(1, 10))))

20

21 # 2. 求:

22 # 1**3 + 2**3 + 3**3 + .... + 9**3的和

23 print(sum(map(lambda x: x**3, range(1, 10))))

24

25 # 3. 求:

26 # 1**9 + 2**8 + 3**7 + .... + 9**1的和

27 print(sum(map(pow, range(1, 10), range(9, 0, -1))))

281,2,3

filter 函数

参数格式:

filter(func, iterable)

参数说明:

func 含有一个形参的数据处理函数,此函数传入的值为iterable

中提供的数据,func将对iterable中的每个元素进行求布尔

值,返回True则保留此数据,返回False则将此数据丢弃

iterable 为提供数据的可迭代对象

返回值:

可迭代对象

作用:

筛选数据

示例见:

filter.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # filter.py

2

3 def is_odd(x):

4 '''此函数判断x是否是奇数,是奇数返回True,否则返回False'''

5 # print(x % 2 == 1)

6 return x % 2 == 1

7

8 # 打印1 ~ 20 的奇数:

9 for x in filter(is_odd, range(20)):

10 print(x)

11

12 print('-------------')

13 for x in filter(lambda x: x % 2 == 1, range(10)):

14 print(x)

15

16 # 生成20以内的全部偶数(不包含20)的列表

17 L = list(filter(lambda x: x % 2 == 0, range(20)))

18 print(L)

19 L2 = [x for x in filter(lambda x: x % 2 == 0, range(20))]

20 print("L2=", L2)

21

22filter.py

练习:

1. 用filter 生成能够提供偶数可迭代对象,生成1 ~ 20 的偶数,

将这些偶数存于列表中,再打印这个列表(不包含20)

2. 用filter函数,将1~100之间所有的素数prime 放入到列表中,

再打印这个列表

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 1. 用filter 生成能够提供偶数可迭代对象,生成1 ~ 20 的偶数,

2 # 将这些偶数存于列表中,再打印这个列表(不包含20)

3

4 flt = filter(lambda x: x % 2 == 0, range(1, 20))

5 L = list(flt)

6 print(L) # [2, 4, 6, 8 ...]

7

8 L2 = [x for x in flt]

9 print("L2=", L2) # 空列表1~20

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 1. 用filter 生成能够提供偶数可迭代对象,生成1 ~ 20 的偶数,

2 # 将这些偶数存于列表中,再打印这个列表(不包含20)

3

4 L = list(filter(lambda x: x % 2 == 0, range(1, 20)))

5 print(L) # [2, 4, 6, 8 ...]

6

7 L2 = [x for x in filter(lambda x: x % 2 == 0, range(1, 20))]

8 print("L2=", L2) # 空列表1~100

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 2. 用filter函数,将1~100之间所有的素数prime 放入到列表中,

2 # 再打印这个列表

3

4

5 # 写一个函数,is_prime(x), 判断如果x是素数返回True, 否则返回False

6 def is_prime(x):

7 if x < 2: # 小于2的数没有素数

8 return False

9 # 大于等于2的数.如果能被2, 3, 4, ... x -1 整数,就不是素数

10 for i in range(2, x):

11 if x % i == 0:

12 return False # x不是素数

13 # 走到此处,则x一定为素数

14 return True

15

16 # 方法1

17 L1 = list(filter(is_prime, range(100)))

18 print("L1=", L1)

19

20 L2 = [x for x in filter(is_prime, range(100))]

21 print("L2=", L2)

22

23 L3 = [x for x in range(100) if is_prime(x)]

24 print("L3=", L3)

25

26

27

28

29

30

312

sorted 函数:

作用:

将原可迭代对象的数据进行排序,生成排序后的列表

格式:

sorted(iterable, key=None, reverse=False)

参数说明:

iterable 用来提供数据的可迭代对象

key 函数是用来提供一个值,这个值将作为排序的依据

reverse 标志用来设置是否为降序排序(默认为升序排序)

示例:

L = [5, -2, -4, 0, 3, 1]

L2 = sorted(L) # [-4, -2, 0, 1, 3, 5]

L3 = sorted(L, reverse=True) #[5, 3, 1, 0, -2, -4]

L4 = sorted(L, key=abs) # L4=[0, 1, -2, 3, -4, 5]

names = ['Tom', 'Jerry', 'Spike', 'Tyke']

sorted(names) # ['Jerry', 'Spike', 'Tom', 'Tyke']

sorted(names, key=len)

练习:

names = ['Tom', 'Jerry', 'Spike', 'Tyke']

排序的依据为字符串的反序:

'moT' 'yrreJ' 'skipS' 'ekyT'

排序的结果为:

['Spike', 'Tyke', 'Tom', 'Jerry']

请问如何用sorted进行排序

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 练习:

2 # names = ['Tom', 'Jerry', 'Spike', 'Tyke']

3 # 排序的依据为字符串的反序:

4 # 'moT' 'yrreJ' 'skipS' 'ekyT'

5 # 排序的结果为:

6 # ['Spike', 'Tyke', 'Tom', 'Jerry']

7 # 请问如何用sorted进行排序

8

9

10

11 def reverse_str(s):

12 '''s绑定需要排序的可迭代对象提供的元素'''

13 r = s[::-1] # 把转原字符串

14 print("要排序的元素:", s, '排序的依据是:', r)

15 return r

16

17 names = ['Tom', 'Jerry', 'Spike', 'Tyke']

18

19 L = sorted(names, key=reverse_str)

20

21 print(L) # ['Spike', 'Tyke', 'Tom', 'Jerry']

22

23

24

25

26

27

28

递归函数 recursion Function

故事:

从前有座山,山上有座庙,庙里有个老和尚讲故事:

从前有座山,山上有座庙,庙里有个老和尚讲故事:

从前有座山,山上有座庙,庙里有个老和尚讲故事:

ContractedBlock.gif

ExpandedBlockStart.gif

1 # recursion_story.py

2

3 def story():

4 print("从前有座山, 山上有座庙,庙里有个老和尚讲故事:")

5 story()

6

7 story()

8

递归函数:

函数直接或间接的调用自身

示例:

# 函数直接调用自身

def f():

f() # 调用自己

f()

# 函数间接调用自身

def fa():

fb() # 调用另一个函数fb

def fb():

fa() # 调用fa

fa()

递归说明:

递归一定要控制递归的层数,当符合某一条件时要终止递归调用

几乎所有的递归都能用while循环来代替

递归的优缺点:

优点:

递归可以把问题简单化,让思路更为清晰,代码更为简洁

缺点:

递归因系统环境影响大,当递归深度太大时,可能会得到不可预知

的结果

递归的两个阶段:

递推阶段: 从原问题出发,按递归公式递推,从未知到已知,最终达到

递归的终止条件

回归阶段: 按递归终止条件求出结果,逆向逐步代入递归公式,回归

原问题求解

递归函数的实现方法:

先假设函数已经实现了原功能,再编写函数

示例见:

recursion.py

# 递归求阶乘示例见:

recursion_factorial.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # recursion.py

2

3 def fx(n):

4 print('递归进入第', n, '层')

5 if n == 3:

6 return

7 fx(n + 1)

8 print('递归退出第', n, '层')

9

10 fx(1)

11 print("程序退出")

12recursio.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # recursion_factorial.py

2 # 1 (如果n为0)

3 # /

4 # n!

5 # \ n * (n-1)! (如果n不为零时)

6

7 def myfac(n):

8 if n == 0: # 0! 为 1

9 return 1

10 else:

11 return n * myfac(n-1) # n! = n * (n-1)!

12

13 print(myfac(5)) # 120recursio_factorial.py

练习:

写一个递归求和函数:

def mysum(n):

...

此函数求 1 + 2 + 3 + 4 + ..... + n 的和

print(mysum(100)) # 5050

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 练习:

2 # 写一个递归求和函数:

3 # def mysum(n):

4 # ...

5 # 此函数求 1 + 2 + 3 + 4 + ..... + n 的和

6

7 # print(mysum(100)) # 5050

8

9

10 def mysum(n):

11 if n == 1:

12 return 1

13 # 其它情况

14 return n + mysum(n-1)

15

16

17 print(mysum(100)) # 5050

18

19mysum

思考题:

已知有五位朋友在一起

第5个人说他比第4个人大2岁

第4个人说他比第3个人大2岁

第3个人说他比第2个人大2岁

第2个人说他比第1个人大2岁

第1个人说他10岁

编写程序求:

1) 算出第五个人几岁

2) 算出第三个人几岁

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 思考题:

2 # 已知有五位朋友在一起

3 # 第5个人说他比第4个人大2岁

4 # 第4个人说他比第3个人大2岁

5 # 第3个人说他比第2个人大2岁

6 # 第2个人说他比第1个人大2岁

7 # 第1个人说他10岁

8 # 编写程序求:

9 # 1) 算出第五个人几岁

10 # 2) 算出第三个人几岁

11

12 def get_age(n):

13 if n == 1:

14 return 10

15 return get_age(n - 1) + 2

16

17 print('第五个人', get_age(5), '岁')

18 print('第三个人', get_age(3), '岁')

19

20

21

闭包 closure

什么是闭包?

闭包是指引用了此函数外部嵌套函数作用域的变量的函数

闭包必须满足三个条件:

1. 必须有一个内嵌函数

2. 内嵌函数必须引用外部函数中的变量

3. 外部函数返回值必须是内嵌函数

全局变量和局部变量的区别:

全局变量:

一直存在,谁都可以访问和修改

局部变量:

只是在函数调用时存在,只能在函数内部进行访问和修改

示例见:

closure.py

closure2.py

closure3.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # closure.py

2

3 # 用全局变量保存压岁钱

4

5 money = 1000 # 爸爸给函数的压岁钱

6

7 def child_buy(obj, m):

8 global money

9 if money > m:

10 money -= m

11 print('买', obj, '花了', m, '元,剩余',

12 money,'元')

13 else:

14 print("买", obj, '失败')

15

16 child_buy("变形金刚", 200)

17 money = 0 # 钱被偷走了

18 child_buy('漫画三国', 100)

19 child_buy('手机', 1300)

20

21

22

23

24

25

261

ContractedBlock.gif

ExpandedBlockStart.gif

1 # closure.py

2

3 # 用局部变量保存压岁钱(不附合逻辑)

4

5 def child_buy(obj, m):

6 money = 1000 # 爸爸给函数的压岁钱

7 if money > m:

8 money -= m

9 print('买', obj, '花了', m, '元,剩余',

10 money,'元')

11 else:

12 print("买", obj, '失败')

13

14 child_buy("变形金刚", 200)

15 child_buy('漫画三国', 100)

16 child_buy('手机', 1300)

17

18

19

20

21

22

232

ContractedBlock.gif

ExpandedBlockStart.gif

1 # closure.py

2

3 # 用外部嵌套函数内的变量保存压岁钱

4

5 def give_yasuiqian(money):

6 def child_buy(obj, m):

7 nonlocal money

8 if money > m:

9 money -= m

10 print('买', obj, '花了', m, '元,剩余',

11 money,'元')

12 else:

13 print("买", obj, '失败')

14 return child_buy # 返回内嵌函数的引用关系

15

16 cb = give_yasuiqian(1000) # 给压岁钱1000

17

18 cb("变形金刚", 200)

19 cb('漫画三国', 100)

20 cb('手机', 1300)

21

22

23

24

25

26

273

闭包的注意事项:

由于闭包会使得函数中的变量都被保存在内存中,内存消耗比较大,所

以不能滥用闭包

闭包的应用示例见:

closure_make_power.py

ContractedBlock.gif

ExpandedBlockStart.gif

1 # closure_make_power.py

2

3 # 此示例示意闭包的应用

4

5 # 写一个求x的平方的函数

6 # def pow2(x):

7 # return x**2

8 # 写一个求x的立方的函数

9 # def pow3(x):

10 # return x**3

11

12 # 写一个求x的102次方的函数

13 # def pow102(x):

14 # return x**102

15

16 # 写一个求x的150次方的函数

17 # def pow150(x):

18 # return x**150

19

20 # 用闭包实现上述功能

21 def make_power(y):

22 def fn(x):

23 return x ** y # y为外部嵌套函数的变量

24 return fn

25

26 pow2 = make_power(2)

27 print('5的平方是:', pow2(5))

28 print('6的平方是:', pow2(6))

29 pow3 = make_power(3)

30 print('7的立方是:', pow3(7))

31 # ....

32 pow150 = make_power(150)

33 print(pow150(2))

34

35

小结:

函数式编程:

高阶函数:

map, filter, sorted

递归函数

闭包

练习:

1. 写程序算出1~20的阶乘的和,即:

1!+2!+3!+4!+......+19!+20!

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 1. 写程序算出1~20的阶乘的和,即:

2 # 1!+2!+3!+4!+......+19!+20!

3

4 def myfac(x):

5 if x == 0:

6 return 1

7 return x * myfac(x-1)

8

9 # 方法1

10 # s = 0

11 # for x in range(1, 21):

12 # s += myfac(x)

13 # print('和是:', s)

14

15 # 方法2

16 print("和是:", sum(map(myfac, range(1, 21))))

17

181

2. 已知有列表:

L = [[3, 5, 8], 10, [[13, 14], 15, 18], 20]

1) 写一个函数print_list(lst) 打印出所有的数字

如:

print_list(L) # 打印 3 5 8 10 13 14 ....

(不要求打印在一行内)

2) 写一个函数 sum_list(lst) 返回这个列表中所有数字的和

如:

print(sum_list(L)) # 打印 106

注:

type(x) 可以返回一个变量的类型

如:

>>> type(20) is int # True

>>> type([1, 2, 3]) is list # True

ContractedBlock.gif

ExpandedBlockStart.gif

1 # 2. 已知有列表:

2 # L = [[3, 5, 8], 10, [[13, 14], 15, 18], 20]

3 # 1) 写一个函数print_list(lst) 打印出所有的数字

4 # 如:

5 # print_list(L) # 打印 3 5 8 10 13 14 ....

6 # (不要求打印在一行内)

7 # 2) 写一个函数 sum_list(lst) 返回这个列表中所有数字的和

8 # 如:

9 # print(sum_list(L)) # 打印 106

10 # 注:

11 # type(x) 可以返回一个变量的类型

12 # 如:

13 # >>> type(20) is int # True

14 # >>> type([1, 2, 3]) is list # True

15

16

17

18 L = [[3, 5, 8], 10, [[13, 14], 15, 18], 20]

19

20 def print_list(lst, newline=False):

21 for x in lst:

22 if type(x) is list: # 如果是列表,则按相同规则打印列表

23 print_list(x)

24 else: # 如果是数字则直接打印

25 print(x, end=' ')

26 if newline:

27 print() # 换行

28

29 print_list(L, True) # 3 5 8 10 13 14 ....

30

31

32 def sum_list(lst):

33 s = 0

34 for x in lst:

35 if type(x) is list:

36 s += sum_list(x)

37 else:

38 s += x

39 return s

40

41 print(sum_list(L)) # 106

42

432

3. 修改之前学生信息的程序

要求添加四个功能

| 5) 按学生成绩高-低显示学生信息 |

| 6) 按学生成绩低-高显示学生信息 |

| 7) 按学生年龄高-低显示学生信息 |

| 8) 按学生年龄低-高显示学生信息 |

ContractedBlock.gif

ExpandedBlockStart.gif

1

2 # 3. 改写之前的学生信息管理程序:

3 # 用两个函数来封装功能的代码块

4 # 函数1: input_student() # 返回学生信息字典的列表

5 # 函数2: output_student(L) # 打印学生信息的表格

6

7 def input_student():

8 L = [] # 创建一个列表,准备存放学生数据的字典

9 while True:

10 n = input("请输入姓名:")

11 if not n: # 如果用户输入空字符串就结束输入

12 break

13 a = int(input("请输入年龄:"))

14 s = int(input("请输入成绩:"))

15 d = {} # 一定要每次都创建一个新的字典

16 d['name'] = n

17 d['age'] = a

18 d['score'] = s

19 L.append(d) # 把d加入列表中L

20 return L

21

22 def output_student(L):

23 print("+---------------+----------+----------+")

24 print("| 姓名 | 年龄 | 成绩 |")

25 print("+---------------+----------+----------+")

26 for d in L:

27 name = d['name']

28 age = str(d['age']) # 转为字符串

29 score = str(d['score']) # 转为字符串

30 print("|%s|%s|%s|" % (name.center(15),

31 age.center(10),

32 score.center(10)))

33 print("+---------------+----------+----------+")

34

35 def delete_student(L):

36 name = input("请输入要删除学生的姓名:")

37 i = 0 # i 代表列表的索引

38 while i < len(L):

39 d = L[i] # d绑定字典

40 if d['name'] == name:

41 del L[i]

42 print("删除", name, "成功!")

43 break

44 else:

45 print("删除失败!")

46

47 def modify_student_score(L):

48 pass

49

50

51 def output_by_score_desc(L):

52 def get_score(d):

53 return d['score']

54 L2 = sorted(L, key=get_score, reverse=True)

55 output_student(L2)

56

57 def output_by_score_asc(L):

58 L2 = sorted(L, key=lambda d:d['score'])

59 output_student(L2)

60

61 def output_by_age_desc(L):

62 L2 = sorted(L, key=lambda d:d['age'], reverse=True)

63 output_student(L2)

64

65 def output_by_age_asc(L):

66 L2 = sorted(L, key=lambda d:d['age'])

67 output_student(L2)

68

69

70

71

72

73 def show_menu():

74 '''显示菜单'''

75 print("+--------------------------------+")

76 print("| 1) 添加学生信息 |")

77 print("| 2) 显示学生信息 |")

78 print("| 3) 删除学生信息 |")

79 print("| 4) 修改学生成绩 |")

80 print("| 5) 按学生成绩高-低显示学生信息 |")

81 print("| 6) 按学生成绩低-高显示学生信息 |")

82 print("| 7) 按学生年龄高-低显示学生信息 |")

83 print("| 8) 按学生年龄低-高显示学生信息 |")

84 print("| q) 退出 |")

85 print("+--------------------------------+")

86

87

88 def main():

89 infos = [] # 此列表用于保存学生数据

90 while True:

91 show_menu()

92 s = input("请选择:")

93 if s == '1':

94 infos += input_student()

95 elif s == '2':

96 output_student(infos)

97 elif s == '3':

98 delete_student(infos)

99 elif s == '4':

100 modify_student_score(infos)

101 elif s == '5':

102 output_by_score_desc(infos)

103 elif s == '6':

104 output_by_score_asc(infos)

105 elif s == '7':

106 output_by_age_desc(infos)

107 elif s == '8':

108 output_by_age_asc(infos)

109 elif s == 'q':

110 break

111

112 main()

1133

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值