常用高阶函数
文章目录
定义:参数或(和)返回值为其他函数的函数
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)
初识面向对象
模拟学生和老师的一天
面向过程(早期语言的编程)
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} 人")
面向过程(结构化编程)
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} 人")
面向对象(高内聚低耦合)
程序 = 数据 + 算法。面向过程编程,更侧重于算法;而面向对象编程更侧重于数据。
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()
总结:初识面向对象
编程语言的历程:
面向过程(早期编程语言)—> 面向过程(结构化编程) —>面向对象
面向过程(早期编程语言):没有复用性
面向过程(结构化编程):提高同类代码的复用性,但几乎没有可拓展性
面向对象:提高复用性、可拓展性