Day11python高阶函数/迭代器/生成器/模块 – Python量化投资

Day11python高阶函数/迭代器/生成器/模块

函数作为变量

1.函数调用表达式

函数调用表达式 — 调用函数的语句

普通值能做的事情函数调用表达式都可以做

def func1(x):
    return x**3
func1(2)
num1 = func1(2)
num = 8 * 2
num2 = func1(2) * 8
list1 = [8, 10]
list2 = [func1(2), 4]

2.函数作为变量

在python中声明函数本质就是声明一个类型为function的变量,函数名就是变量名

变量能做的是事情函数都可以做

# 声明一个类型是function的变量, func4是变量
def func4(x):
    print('函数:', x)
a = 10
print(type(a), type(func4))
# 1)一个变量可以给另外一个变量赋值
print('================给变量赋值===============')
b = a
print(b+20)
c = func4
print(c(100))
# 2)给变量重新赋值
a = 'abc'
print(a)
func4 = 321
print(func4*2)
# func4(3)     # TypeError: 'int' object is not callable
# 3)变量作为容器的元素
a = 10
list1 = [a, 10]
print(list1[0]/2)
def func4(x):
    print('函数:', x)
list1 = [func4, func4(20)]
print(list1[1])
print(list1[0](9))   # print(func4(9))
list1 = [
    {'a': 10, 'f': func4},
    100
]
print(list1[0]['f'](100))    # func4(100)
def func5():
    return [1, 2, 3]
list1 = [
    {'a': 10, 'f': func5},
    100
]
print(list1[0]['f']()[1])   # [1, 2, 3][1]
# 4)变量可以作为函数的参数
"""
一个函数可以作为另外一个函数的参数
如果一个函数的参数也是函数,那么这种函数叫实参高阶函数
"""
def func61(a=0):
    return a*2
# 参数x的类型必须是函数
def func6(x):
    # x = func61
    x()    # x()是调用函数的语句; func61()
func6(func61)
def func7(x):
    return x(10) + 100   # x是函数,并且能够接收一个参数,返回值是数字

实参高阶函数:列表.sort()、sorted()、max(), min()

nums = [1, 78, 9, 78, 67, 100]
print(nums.sort())
print(nums)
nums = (1, 78, 9, 78, 67, 100)
print(sorted(nums))
print(nums)
  • a.sort和sorted

这两个函数是实参高阶函数,里面有个参数key要求传一个函数

key参数对应的函数是用来决定排序规则: 函数需要一个参数和一个返回值, 它的参数代表需要排序的序列的元素,返回值是比较对象

# 数字列表, 排序规则发生改变: 按照数字的个位数从小到大排序
nums = [21, 69, 367, 78, 478, 5100]
# key对应的函数1: 按照元素本身大小进行排序
# [21, 69, 367, 78, 478, 5100]
def func(item):
    return item
# key对应的函数2: 按照 元素%10 的值的大小进行排序
def func1(item):
    return item % 10
# key对应的函数3:按照元素的最高位的值进行从小到大排序
def func2(item):
    return int(str(item)[0])
nums.sort(key=func2)    # 按照元素本身大小进行排序
print(nums)

练习:给一个数字列表,按照各位数的和的大小从小到大排序

nums = [12, 67, 18, 90, 890, 123, 99]    # [3, 13, 9, 9, 17, 6, 18]
# nums = [12, 123, 18, 90, 67, 890, 99]
def func3(item):
    sum1 = 0
    for ch in str(item):
        sum1 += int(ch)
    return sum1
nums.sort(key=func3)
print(nums)

练习


all_student = [
    {'name': '小明1', 'age': 23, 'score': 89, 'id': '001'},
    {'name': '小明2', 'age': 30, 'score': 70, 'id': '002'},
    {'name': '小明3', 'age': 18, 'score': 99, 'id': '003'},
    {'name': '小明4', 'age': 21, 'score': 40, 'id': '004'}
]
def func4(item):
    return item['score']
all_student.sort(key=func4)
# all_student.sort(key=func4, reverse= True)  从大到小排序
print(all_student)

3. 变量作为函数的返回值

一个函数的返回值如果也是一个函数那么这个函数就是返回值高阶函数

# func1是返回值高阶函数,因为它的返回值是一个函数
def func1():
    def func11():
        return 10
    return func11
print(func1()())   # print(func11())  print(10)

迭代器

1.什么是迭代器

迭代器是容器型数据类型(序列),可变(不支持增删改),有序(不支持下标操作)

保存在迭代器中的元素,只能取,并且取出来后迭代器就不再保存,也不可以在往迭代器中添加元素

迭代器没有对应格式的数据,迭代器只能是通过其他的序列转换成迭代器,或者是生成器

iter1 = iter([1, 2, 3, 4])
print(iter1)
iter2 = iter('adsa')
print(iter2)

2. 获取迭代器的元素

不管用什么样的方式去获取迭代器中的元素,获取一个就会少一个

  • a 获取单个元素:next.(迭代器) — 获取迭代器中的最顶层元素(也就是第一个元素)
iter2 = iter('adsa')
print(next(iter2))
print(next(iter2))
  • b 遍历
iter2 = iter('adsa')
for x in iter2:
    print(x)

生成器

1. 什么是生成器

生成器本身就是迭代器 —- 获取元素和迭代器是一样的,只能一个一个的取 取一个就会少一个

调用函数体中只要有yield关键字的函数就可以得到一个生成器

2. yield

yield只能出现在函数体中

调用yield关键字的函数,不会执行函数体,也不会获取返回值,而是得到一个生成器

def func1():
    yield 
    print('dd')
    return 12
    
print(func1())

3.生成器怎么产生数据

看一个生成器能够产生几个数据,就看执行完生成器对应的函数会遇到几个yield

yield后面的值就是生成器的元素(就是生成器产生的数据)

def func2():
    yield 100
gen1 = func2()
print(gen1)
print(next(gen1))
def func2():
    for x in range(10):
        yield x
gen1 = func2()
print(gen1)
print(next(gen1))

4. 生成器产生数据的原理

生成器不会同时将序列的元素保存起来,而是需要数据的时候就会产生临时的数据

每次获取生成器元素的时候,就会执行生成器对应的函数的函数通体,从前往后执行

直到遇到yield为止,并且将yield后面的值作为结果

同时会保存上次结束的位置,下次获取下一个元素的时候接着上次结束的位置往后执行,直到遇到下一个yield

以此类推

如果执行函数结束都没有遇到yield,next函数就会报 stopIteration 的错误


def func3():
    print('======1====')
    yield 1
    print('======2====')
    yield 2
    print('======3====')
    yield 3
gen2 = func3()
print(next(gen2))
print('开始取第二个数据')
print(next(gen2))
print('开始取第三个数据')
print(next(gen2))

写一个产生学好的生成器

def create_id():
    num = 1 
    while 1:
        yield 'stu' + str(num)
        
nums = create_id()
print(next(nums))
for x in range(100):
    print(next(nums))

生成式

1.什么是生成式

生成式的本质就是生成器

a.语法1:
(表达式 for 变量 in 序列)  -----  创建一个生成器
展开成生成器:
def func1():
    for 变量 in 序列:
        yield 表达式
[表达式 for 变量 in 序列]   ----- 将生成式对应的生成器转换成一个列表
b.语法2 
(表达式 for 变量 in 序列 if 条件语句) ----- 创建一个生成器
展开成生成器:
def func():
    for 变量 in 序列:
        if 条件语句:
            yield 表达式

练习

# gen1是生成器
gen1 = (x*2 for x in range(10))
print(next(gen1))
print(next(gen1))
print(next(gen1))
list1 = list(gen1)
print(list1)   # [4, 6, 8, 10, 12, 14, 16, 18]
'''
def func():
    for x in range(10):
        yield x*2
gen1 = func()
'''
#
list2 = [x*x for x in range(1, 10)]
print(list2)
#
list3 = list(x*x for x in range(1, 10))
print(list3)
#
dict1 = dict((x, x*2) for x in range(5))
print(dict1)
#
list4 =[x for x in range(10) if x % 2]
print(list4)
#
list5 = ['%d*2=%d' % (x, x*2) for x in range(5)]
print(list5)

模块的使用

在实际开发的时候一个项目会被分为多个模块

1.什么是模块:一个py文件就是一个模块

2.多模块怎么协作:导入模块

a. import 模块名 ---- 在当前模块中导入指定模块,导入后可以使用指定模块中所有的全局变量
                     以’模块名.变量‘的方式去使用
b. from 模块名 import 全局变量1,全局变量...
                ---- 导入的内容不同,导入指定模块中指定的全局变量;被导入的全局变量在当前的模块中直接使用
c.重命名:
import 模块名 as 新模块名 ----- 模块重命名,通过新的模块名使用模块
from 模块名 import 变量1 as 新变量1, 变量2 as 新变量2, ..   --- 变量重命名,通过新变量去使用变量
d.通配符
from 模块名 import *    -----  导入模块中所有的全局变量,使用的时候直接用

3.导入模块的原理

当执行导入模块代码的时候,实质会执行被导入的模块对应的py文件

将不希望被别的模块执行的代码放到下面的if语句中


if __name__ == '__main__':
    print()
「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
Python