【三十二】高阶函数、递归函数和面向对象

常用高阶函数

定义:参数或(和)返回值为其他函数的函数

filter(function, iterable)

  • function:函数(function 必需能够接受1个实参),也可以为 None
  • iterable:可迭代对象
  • 将 iterable 中每个元素作为参数传递给函数,根据函数的返回结果进 行判断 True 或 False,将判断为 True 的 iterable 中的元素构建新的迭代器并返回
  • 如果 function 为 None,直接判断 iterable 中元素 True 或 False,再 返回为 True 的元素构建的新的迭代器
# 思考:如果换成 lambda x: print(x-1) 会怎样?
object1 = filter(lambda x: x - 1, [1, 2, 3, False, 4])
print(list(object1))  # [2, 3, False, 4]
object3 = filter(None, [1, 2, 0, 3, False, 4])
print(list(object3))  # [1, 2, 3, 4]

map(func, *iterables)

  • func:函数(func 必需能够接收 iterables 个数的实参)
  • iterables:可迭代对象 用 iterables 中的每个元素作为函数的参数来调用函数,以迭代器形式返回所有结果
  • 当有多个 iterables 对象时,最短的 iterables 耗尽则函数停止
def square(a):
    return a ** 2  # 思考:如果改为 print(a**2) 会怎样?


result = map(square, [1, 2, 3])
print(list(result))  # [1, 4, 9]

result = map(lambda a: a ** 2, [1, 2, 3])
print(list(result))  # [1, 4, 9]

result = list(map(float, ["1", "2", "3"]))
print(result)  # [1.0, 2.0, 3.0]

# 类似于zip的取元素方式
result = list(map(lambda x, y, z: x + y + z, [1, 2, 3], [3, 2, 1], [1, 3, 2]))
print(result)  # [5, 7, 6]

# 当有多个 iterables 对象时,最短的 iterables 耗尽则函数停止
result = list(map(lambda x, y, z: x + y + z, [1, 2, 3], [3,
                                                         2, 1], [1, 3]))
print(result)  # [5, 7]

reduce(function, iterable[, initial])

  • function:函数(function 必需能够接收两个实参)
  • iterable:可迭代对象
  • initial:初始值
  • 在 Python2 中 reduce() 是内置函数,而在Python3中 reduce() 函数是 在functools模块中的,所以在使用的时候需要先导入 functools 模块
  • 在没有指定 initial 参数时,先把 iterable 的前两个元素作为参数调用 函数,把这次函数的结果以及iterable 的下一个元素又作为参数再调用 函数,以此类推
  • 在指定 initial 参数时,先把 initial 值和 iterable 的第一个元素作为参 数调用函数,把这次函数的结果以及 iterable 的下一个元素又作为参 数再调用函数,以此类推
  • 如果 iterable 为空,返回 initial ,此时如果没有指定 initial,则报错
  • 如果 iterable 只有一个元素且没有指定 initial,返回该元素
from functools import reduce


def add(m, n):
    s = m + n
    return s  # 如果改为 print(s) 会怎样?


# 过程:[(1+2)+3]+4 = 10
result = reduce(add, [1, 2, 3, 4])
print(result) # 10

# 过程:2*[2*(2*5+1)+2]+3 = 51
result = reduce(lambda x, y: 2 * x + y, [1, 2, 3], 5)
print(result) # 51

# iterable为空,返回initial
result = reduce(lambda x, y: 10 * x + 2 * y, [], 123)
print(result)  # 123

# iterable只有一个元素且没有指定 initial,返回该元素
result = reduce(lambda x, y: 10 * x + 2 * y, [123])
print(result)  # 123

# 过程:10*2 + 2*123 = 266
result = reduce(lambda x, y: 10 * x + 2 * y, [123], 2)
print(result)

递归函数(了解)

定义:程序调用自身的编程技巧称为递归。

思想:将一个大问题分解成一个个的小问题,然后再从小问题回推出大问题

一般来说,递归函数要满足2个条件:

  • 递归边界条件(一般到递归边界则终止当前递归)
  • 递归推理(一般是提取重复的子问题,不断向递归边界靠拢或者不断 缩小问题规模)

兔子问题

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对 小兔子来。如果所有兔子都不死,那么怎么确定第 n 个月有多少对兔子呢?

# 循环实现
def func(m):
    m0 = 1
    m1 = 1
    for _ in range(m-1):
   		 m0, m1 = m1, m0+m1
    return m1

for i in range(10):
	print(func(i))
    
# 递归实现
def get_rabbits(m):
    if m < 2:
    	return 1
	return get_rabbits(m-1) + get_rabbits(m-2)


print(get_rabbits(12))

最大递归深度限制

def get_rabbits(m):
	if m < 2:
		return 1
	return get_rabbits(m-1) + get_rabbits(m-2)

print(get_rabbits(998))
print(get_rabbits(999))

import sys
def get_rabbits(m):
	if m < 2:
		return 1
	return get_rabbits(m-1) + get_rabbits(m-2)


print(sys.getrecursionlimit()) # 返回默认的最大递归深度1000
sys.setrecursionlimit(1500) # 设置最大递归深度为1500
print(get_rabbits(999)) # 放宽最大递归深度之后不报错了

解决递归重复计算问题

当 m 比较大时,比如 m=50,会发现程序计算会变得非常慢,因为递归程序进 行了大量的重复计算;要解决递归的重复计算问题,只要把之前已经计算过的 数和结果储存起来,后面如果再计算这个数就直接取结果

store={}
def get_rabbits(m):
	if m < 2:
		return 1
    
if m in store:
	return store[m]

result = get_rabbits(m-1) + get_rabbits(m-2)
store[m] = result
return result

for m in range(1000):
    result = get_rabbits(m)
    if m == 999: print(result)
    

初识面向对象

模拟学生和老师的一天

面向过程(早期语言的编程)

image-20230304104056434

count_s = 0
stu1 = "张三"
age_s = 18
adres_s = "黄土高坡"

print(f"大家好! 我是{stu1}, 今年{age_s}, 家住在{adres_s},
欢迎大家有空来玩哦!")
      
count_s += 1
print(f"{stu1}起床")
print(f"{stu1}刷牙")
      
print(f"{stu1}洗脸")
print(f"{stu1}吃菜")
      
print(f"{stu1}扒饭")
print(f"{stu1}账号登录成功")
      
print(f"{stu1}看视频")
print(f"{stu1}写代码")
      
print(f"{stu1}吃菜")
print(f"{stu1}扒饭")
      
print(f"{stu1}看视频")
print(f"{stu1}写代码")
      
print(f"{stu1}吃菜")
print(f"{stu1}扒饭")
      
print(f"{stu1}刷牙")
print(f"{stu1}洗脸")
      
print(f"{stu1}睡觉")
      
print(f"当前统计的学生人数是: {count_s} 人")
count_t = 0
teacher1 = "老王"
age_t = 40
adres_t = "人民广场"

print(f"大家好! 我是{teacher1}, 今年{age_t}岁, 家住在{adres_t}, 欢迎大家有空来玩哦!")

count_t += 1

print(f"{teacher1}起床")

print(f"{teacher1}刷牙")
print(f"{teacher1}洗脸")

print(f"{teacher1}吃菜")
print(f"{teacher1}扒饭")

print(f"{teacher1}今日打卡成功")

print(f"{teacher1}授课")
print(f"{teacher1}答疑")
print(f"{teacher1}写代码")

print(f"{teacher1}吃菜")
print(f"{teacher1}扒饭")

print(f"{teacher1}授课")
print(f"{teacher1}答疑")
print(f"{teacher1}写代码")

print(f"{teacher1}吃菜")
print(f"{teacher1}扒饭")

print(f"{teacher1}刷牙")
print(f"{teacher1}洗脸")

print(f"{teacher1}睡觉")

print(f"当前统计的老师人数是: {count_t} 人")

面向过程(结构化编程)

image-20230304104337393

count_s = 0
stu1 = "张三"
age_s = 18
adres_s = "黄土高坡"

print(f"大家好! 我是{stu1}, 今年{age_s}岁, 家住在{adres_s},欢迎大家有空来玩哦!")

count_s += 1


def wash(name):
    print(f"{name}刷牙")
    print(f"{name}洗脸")
    
    
def eat(name):
    print(f"{name}吃菜")
    print(f"{name}扒饭")
    
    
def study(name):
    print(f"{stu1}看视频")
    print(f"{stu1}写代码")
    print(f"{stu1}起床")
    
    
wash(stu1)

eat(stu1)

print(f"{stu1}账号登录成功")

study(stu1)

eat(stu1)

study(stu1)

eat(stu1)

wash(stu1)

print(f"{stu1}睡觉")

print(f"当前统计的学生人数是: {count_s} 人")
count_t = 0
teacher1 = "老王"
age_t = 40
adres_t = "人民广场"

print(f"大家好! 我是{teacher1}, 今年{age_t}岁, 家住在{adres_t}, 欢迎大家有空来玩哦!")

count_t += 1

def wash(name):
    print(f"{name}刷牙")
    print(f"{name}洗脸")
    
    
def eat(name):
    print(f"{name}吃菜")
    print(f"{name}扒饭")
    
    
def work(name):
    print(f"{name}授课")
    print(f"{name}答疑")
    print(f"{name}写代码")
    print(f"{teacher1}起床")
    
    
wash(teacher1)

eat(teacher1)

print(f"{teacher1}今日打卡成功")

work(teacher1)

eat(teacher1)

work(teacher1)

eat(teacher1)

wash(teacher1)

print(f"{teacher1}睡觉")

print(f"当前统计的老师人数是: {count_t} 人")

面向对象(高内聚低耦合)

image-20230304104601325

程序 = 数据 + 算法。面向过程编程,更侧重于算法;而面向对象编程更侧重于数据。

class Student:
	count = 0
    
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        self.show_time()
        Student.count += 1
        
        
	def show_time(self):
        print(f"大家好! 我是{self.name}, 今年{self.age},
        家住在{self.address}, 欢迎大家有空来玩哦!")
              
              
    def get_up(self):
        print(f"{self.name}起床")
              
    def wash(self):
        print(f"{self.name}刷牙")
        print(f"{self.name}洗脸")
              
              
    def eat(self):
        print(f"{self.name}吃菜")
        print(f"{self.name}扒饭")
              
              
    def login_ID(self):
    	print(f"{self.name}账号登录成功")
              
              
    def study(self):
        print(f"{self.name}看视频")
        print(f"{self.name}写代码")

   def login_ID(self):
		print(f"{self.name}账号登录成功")
              
              
	def study(self):
		print(f"{self.name}看视频")
		print(f"{self.name}写代码")
	
     def sleep(self):
		print(f"{self.name}睡觉")

     @classmethod
	def counter(cls):
		print(f"当前统计的学生人数是: {cls.count} 人")


stu1 = Student("张三", 18, "黄土高坡")
stu1.get_up()
stu1.wash()
stu1.eat()
stu1.login_ID()
stu1.study()
stu1.eat()
stu1.study()
stu1.eat()
stu1.wash()
stu1.sleep()
stu1.counter()

class Teacher:
	count = 0
    
    
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        self.show_time()
        
Teacher.count += 1

    def show_time(self):
        print(f"大家好! 我是{self.name}, 今年{self.age}岁,家住在{self.address}, 欢迎大家有空来玩哦!")

    def get_up(self):
		print(f"{self.name}起床")

        
    def wash(self):
   	    print(f"{self.name}刷牙")
		print(f"{self.name}洗脸")
        
        
    def eat(self):
        print(f"{self.name}吃菜")
        print(f"{self.name}扒饭")
        
        
	def clock_in(self):
        print(f"{self.name}今日打卡成功")
        
        
    def work(self):
        print(f"{self.name}授课")
        print(f"{self.name}答疑")
        print(f"{self.name}写代码")
        
        
    def sleep(self):
   	    print(f"{self.name}睡觉")
        
        
	@classmethod
	def counter(cls):
		print(f"当前统计的老师人数是: {cls.count} 人")

        
teacher1 = Teacher("老王", 40, "人民广场")
teacher1.get_up()
teacher1.wash()
teacher1.eat()
teacher1.clock_in()
teacher1.work()
teacher1.eat()
teacher1.work()
teacher1.eat()
teacher1.wash()
teacher1.sleep()
teacher1.counter()
class Person:
    def __init__(self, name, age, address):
        self.name = name
        self.age = age
        self.address = address
        self.show_time()
        
        
    def show_time(self):
   	    print(f"大家好! 我是{self.name}, 今年{self.age}岁,家住在{self.address}, 欢迎大家有空来玩哦!")
        
        
    def get_up(self):
    	print(f"{self.name}起床")
        
        
    def wash(self):
        print(f"{self.name}刷牙")
        print(f"{self.name}洗脸")
        
        
    def eat(self):
        print(f"{self.name}吃菜")
        print(f"{self.name}扒饭")
        
        
    def sleep(self):
    	print(f"{self.name}睡觉")

class Student(Person):
	count = 0
    
    
	def __init__(self, name, age, address, classes):
		super().__init__(name, age, address)
		self.classes = classes
        
	Student.count += 1
    
    def login_ID(self):
   		print(f"{self.name}账号登录成功")
        
	def study(self):
        print(f"{self.name}看视频")
        print(f"{self.name}写代码")
    
    @classmethod
	def counter(cls):
		print(f"当前统计的学生人数是: {cls.count} 人")
        
class Teacher(Person):
	count = 0
    
	def __init__(self, name, age, address, department):
		super().__init__(name, age, address)
		self.department = department
        
        
Teacher.count += 1


    def clock_in(self):
    	print(f"{self.name}今日打卡成功")
        
        
    def work(self):
   	    print(f"{self.name}授课")
		print(f"{self.name}答疑")
		print(f"{self.name}写代码")
        
    @classmethod
	def counter(cls):
		print(f"当前统计的老师人数是: {cls.count} 人")

stu1 = Student("张三", 18, "黄土高坡", "高三1班")
Student.counter()
teacher1 = Teacher("老王", 38, "人民广场", "教育部")
teacher2 = Teacher("老翁", 39, "黄浦江", "教育部")
teacher3 = Teacher("老李", 40, "黄浦江", "教导处")
Teacher.counter()

总结:初识面向对象

编程语言的历程:

面向过程(早期编程语言)—> 面向过程(结构化编程) —>面向对象

面向过程(早期编程语言):没有复用性

面向过程(结构化编程):提高同类代码的复用性,但几乎没有可拓展性

面向对象:提高复用性、可拓展性

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值