一  生成器

# 函数内但凡出现yield关键字,再调用函数不会执行函数体代码,会得到一个生成器对象
# 生成器就是一种自定义的迭代器

# yiled vs retunrn:
# 相同点:返回值层面一样
# 不同点:return只能返回一次值函数就立即结束,而yiled可以返回多次值

# 案例
def func():
    print('01')
    yield 1
    print('02')
    yield 2
    print('03')
    yield 3

abc = func()
res1 = next(abc)  # 01
res2 = next(abc)  # 02
res3 = next(abc)  # 03

二  生成式

# 1.列表生成式
names = ['a', '1', 'b', 'c', '6', '7', '8']

# new_1 = []
# for name in names:
#     if not name.isdigit():
#         new_1.append(name)

new_1 = [name for name in names if not name.isdigit()]
print(new_1)

# 2.字典生成式
res = {i: i ** 2 for i in range(5)}
print(res)

# 3.集合生成式
res = {i for i in range(5)}
print(res)

# 4.生成器表达式
res = (i for i in range(5))
print(next(res))

三  面向过程编程

# 面向过程编程是一种编程思想or编程范式
# 优点:复杂的问题流程化、进而简单化
# 缺点:牵一发而动全身,扩展性差

四  函数递归调用

# 函数递归调用:函数嵌套调用的一种特殊形式
# 指的是调用函数的过程中直接或间接的调用自己
# 案例
def f1():
    print('from f1')
    f1()


# 实际上递归的过程分两阶段:
# 1.回溯:向下一层一层调用
# 2.递推:向上一层一层返回
def age(n):
    if n == 1:
        return 18
    return age(n - 1) + 10


res = age(5)
print(res)

五  二分法

# 将找的值分为两份,取中间值
# 案例
nums = [5, 10, 20, 30, 40, 50, 60, 70, 80]

find_num = 40


def search(find_num, nums):
    print(nums)
    if len(nums) == 0:
        print('not exists')
        return
    mid_index = len(nums) // 2
    if find_num > nums[mid_index]:
        new_nums = nums[mid_index + 1:]
        search(find_num, new_nums)
    elif find_num < nums[mid_index]:
        new_nums = nums[:mid_index]
        search(find_num, new_nums)
    else:
        print('find it')


search(60, nums)

六  匿名函数

achievement = {
    'xm': 90,
    'xh': 95,
    'xf': 100,
}

print(max(achievement,key=lambda k:achievement[k]))
print(min(achievement,key=lambda k:achievement[k]))
print(sorted(achievement))

七  模块的使用

'''
1. 什么是模块(模块是一系列功能的集合体)

模块分为四种类别:
    a.一个py文件就可以是一个模块
    b.包:就是一个存放有__inint__.py文件的文件夹
    c.使用c编写并链接到python解释器的内置模块
    d.已被编译为共享库或DLL的C或C++扩展

模块三种来源:
    a.python内置(import time)
    b.第三方的库
    c.自定义的库

2. 为何要用模块
    1.提升开发效率
    2.解决代码冗余问题

3.如何要用模块
    学习自定义库(记懂创造又知道模仿)

'''

#首次导入模块发生三件事(模块spam.py)
#1.会触发spam.py运行,产生一个模块的名称空间
#2.运行spam.py的代码,将运行过程中产生的名字都丢掉模块名称空间中
#3.在当前执行文件的名称空间中拿到一个名字spam,该名字就是指向模块的名称空间

八  import,from import

#import ATM import start(导入比较准确,但每次都得加前缀)
#from ATM import start(可以节省时间,但容易冲突)

#导模块可以导入多个,用逗号隔开。from ATM import *导入模块用*可以全导里面的名字

九  循环导入问题

#循环导入要把名字往前提
#循环导入问题最好的解决办法就是尽量不用循环导入

十  模块的搜索路径

# 优先级(1.内存,2.内置 3.sys.path:强调sys.path是以执行程序为准的)