递归,二分法,面向对象,类

day26

递归

# 例子1:问年龄
def age(n):
    if n == 1:
        return 10
    else:
        return age(n - 1) + 2
print(age(5))  # 结果为18


# 例子2:
def func(n):
    if n == 10:
        return
    print("from func..")
    func(n - 1)
func(10)

递归深度查看与设置:

import sys
print(sys.getrecursionlimit())  # 获取到最大递归深度为 1000
sys.setrecursionlimit(10000)  # 将递归深度设置设为1万,虽然调了但是如果内存不够的话也没什么用,执行深度太深的话会报错

递归特点:
1. 必须有一个明确的结束条件
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用时通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

递归用途:递归用在不知道循环多少次的情况下

例子3:列表是从小到大有序排列的,传入数字18查询列表里是否存在

思路:如果列表值有10万个的时候,而要判断的值在列表靠后的位置,使用循环则需要循环9万多次才能找到,效率很低;

      所以使用二分法+递归来实现,先和中间的值作比较,如果中间这个值小于传入的18就将列表进行切片和右边的一半进行比较,反之和左边的另一半进行比较。

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 30, 32, 33, 35]

# 传统方式:
num = 18
i = 0
while True:
    if num == data[i]:
        print("---》 传统方式:find it.")
        break
    i += 1

# 递归方式
def search(num, data):
    print(data)  # 打印每次data的值
    lenth = len(data)
    if lenth > 1:  # 当切片后的值大于1个时继续切片并判断
        mid_index = int(lenth / 2)  # 如果为小数会转为整数
        mid_value = data[mid_index]
        if num > mid_value:
            # 进入右边开始切
            data = data[mid_index:]
            search(num, data)
        elif num < mid_value:
            # 进入左边开始切
            data = data[:mid_index]
            search(num, data)
        else:
            print("--》递归方式:find it")
            return
    else:  # 当切片后的值只有1个时,单独判断值是否一致
        if data[0] == num:
            print("--》递归方式:find it")
        else:
            print("--》递归方式:不存在")


search(16, data)

输出结果:

[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 24, 30, 32, 33, 35]
[1, 3, 6, 7, 9, 12, 14, 16, 17]
[9, 12, 14, 16, 17]
[14, 16, 17]
--》递归方式:find it

函数式编程

不会改变外部值的状态
代码精简,但可读性差

python不是一种严格意义上的函数式编程语言编程方式不适合python,但也提供了一些相关的东西,如lambda,filter,map,reduce

面向对象的程序设计

参考博客:http://www.cnblogs.com/linhaifeng/articles/6182264.html

优点:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如游戏中一个任务参数的特征和技能修改都很容易。
缺点:可控性差。

class Garen:
    camp = "Demacia"  # 在类里声明一个变量

    def attack(self): #
        print("attack")

如何实使用类:

一:实例化

obj = Garen()  # 实例化,obj为对象
print(obj)   # 结果为:<__main__.Garen object at 0x000001EF65838EF0>
print(obj.attack()) # 得到结果 attack

二:引用类的特征(类的变量)和技能(类的函数)

print(Garen.camp)   # 结果得到camp的值 Demacia
print(Garen.attack)   # 结果得到 <function Garen.attack at 0x000001EF658398C8>
print(Garen.attack(123123))  # 得到结果 attack

说明:

通过类名调用类里面的attack(),此时attack(self)为一个函数,里面的位置参数self需要按照函数的规范进行传递。

实例化后的对象调调里面的attack(),此时的attack(self)为一个方法,在调用时,里面的self就是对象名,会自动传递即obj.attack(obj),所以不用加参数.

例子2:

__init__()方法与参数

class Garen:
    camp = "Demacia"

    def __init__(self, nickname):
        self.nick = nickname  # 相当于 g1.nick = "草丛伦"

    def attack(self, enemy):
        print("%s attack %s" % (self.nick, enemy))


g1 = Garen("草丛伦")  # 实例化会自动触发类里面 __init__() 的运行,而__init__()有一个nickname参数也需要传递
g1.attack("alex")  # 方法有一个新的位置参数enemy,调用时需要传递,结果为:草丛伦 attack alex

g2 = Garen("贱人")
g2.attack("张三")  # 结果为:贱人 attack 张三

总结:

类: 一:实例化, 二:引用名字(类名.变量名,类名.函数名)

实例:引用名字(实例名.类的变量,实例名.绑定方法,实例名.实例自己的变量名)

增删改查:

# 查
print(Garen.camp)  

# 改
Garen.camp = "aaaa"  
print(Garen.camp)

# 删
del Garen.camp  

# 增
Garen.x = 1  
print(Garen.x)
# 查
g1 = Garen("alex")
print(g1.nick)

# 改
g1.nick = "asb"
print(g1.nick)

# 删
del g1.nick
print(g1.nick)

# 增
g1.sex = "female"
print(g1.sex)

复习:

面向对象的程序设计(OOD)

    找对象-----> 找类(归纳对象共同的特征与技能,还有每个对象独有的特征)

面向对象的编程(OOP)

    先定义类-------> 再实例化出对象

# OOD: 定义学生类

特征:共同国籍“China”

技能:查看成绩

独有的特征:ID、名字、性别、省

# OOP:

class Student:
    country = "China"
    
    def __init__(self, ID,NAME,SEX,PROVINCE ):
        self.id = ID
        self.name = NAME
        self.sex = SEX
        self.province = PROVINCE
        
    def search_score(self):
        print("tell score")
        
    def study(self):
        print("study")
        
# 实例化
s1 = Student("124345463243223", "cobila", "female", "sahngxi")
# 上面实例化就相当于以下,会触发__init__()方法:
Student.__init__(s1, "124345463243223", "cobila", "female", "sahngxi")

s2 = Student("124345463223511", "goudan", "female", "zhejiang")

# 对象可以使用类里的特征和技能了:
s1.search_score()
s1.study()

s2.study()

版权声明:
作者:admin
链接:https://www.chenxie.net/archives/1661.html
来源:蜀小陈
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>