day12-实参高阶函数迭代器和生成器

本文详细介绍了Python中的函数概念,包括函数作为变量的特性,以及如何使用lambda和def定义函数。重点讲解了高阶函数map的使用,通过实例展示了如何处理多个序列元素。同时,深入探讨了reduce函数,用于序列元素的合并操作。此外,还解释了迭代器和生成器的概念,以及如何创建和使用它们。最后,提到了模块的导入和使用方法,包括import和from...import的不同用法。
摘要由CSDN通过智能技术生成

函数的本质

1. 函数就是变量

Python中定义函数其实就是定义一个类型是function的变量,函数名就是变量名

变量 = lambda 参数列表:返回值

相当于:
def 变量(参数列表):
    return 返回值

实参高阶函数

1. map - 将一个或者多个序列中的元素通过指定规则创建一个新的序列

map(函数, 序列) - 将序列中的元素通过函数指定的规则转换成一个新的序列中的元素
函数要求: 有且只有一个参数 - 指向后面的这个序列中的每个元素
有一个返回值 - 新序列中元素(用参数来代表原序列中的元素,描述出新序列中元素和原序列元素的关系)

map(函数, 序列1, 序列2) - 将两个序列中的元素通过函数指定的规则转换成一个新的序列中的元素
函数的要求:有且只有两个参数 - 分别指向后面两个序列中的元素
有一个返回值 - 新序列中元素(用参数来代表原序列中的元素,描述出新序列中元素和原序列元素的关系)

map(函数, 序列1, 序列2, 序列3)
函数的要求:有且只有三个参数 - 分别指向后面三个序列中的元素
有一个返回值

练习1: 获取nums中所有元素的个位数 -> [4, 2, 7, 0, 1]

# 方法一:列表推导式
new_nums = [x % 10 for x in nums]
print(new_nums)

# 方法二:map
new_nums = list(map(lambda x: x % 10, nums))
print(new_nums)

练习2:创建一个序列,序列中的元素是nums1和nums2对应位置上元素的和 - [32, 97, 97, 25]

nums1 = [23, 8, 90, 2]
nums2 = [9, 89, 7, 23]
new_nums = list(map(lambda x1, x2: x1 + x2, nums1, nums2))
print(new_nums)     # [32, 97, 97, 25]

练习3:通过将nums中的元素乘以10转换成一个新的序列 -> [230, 80, 900, 20]

nums = [23, 8, 90, 2]
# 方法一:
new_nums = [x * 10 for x in nums]

# 方法二:
new_nums = list(map(lambda x: x * 10, nums))
print(new_nums)

练习4:已知两个数字列表,将第一个列表中元素的个位数作为十位数,第二个列表中元素的个位数作为个位数创建一个新的序列

# [39, 89, 47, 21]
nums1 = [23, 8, 914, 2]
nums2 = [9, 89, 37, 231]
new_nums = list(map(lambda x1, x2: x1 % 10 * 10 + x2 % 10, nums1, nums2))
print(new_nums)

new_nums = list(map(lambda x1, x2: int(f'{x1%10}{x2%10}'), nums1, nums2))
print(new_nums)

练习5:已经两个列表分别是学生姓名和年龄,根据创建一个保存多个学生信息的列表

# [{'name': '小明', 'age': 18}, {'name': '张三', 'age': 21}, {'name': '李四', 'age': 22}, {'name': '老王', 'age': 19}]
names = ['小明', '张三', '李四', '老王']
ages = [18, 21, 22, 19]

students = list(map(lambda name, age: {'name': name, 'age': age}, names, ages))
print(students)


def temp(name, age):
    """临时函数"""
    return {'name': name, 'age': age}


students = list(map(temp, names, ages))
print(students)

2.reduce - 将序列中的元素按照指定的规则合并成一个数据

reduce(函数, 序列, 初始值)
函数的要求: 有且只有两个参数 - 第一个参数指向初始值,第二个参数指向序列中的元素
返回值 - 确定合并方式(看元素和初始值进行什么样的操作来进行合并的)
from functools import reduce
练习1: 求nums中所有元素的和 -> 118 => 0 + 10 + 20 + 32 + 56

nums = [10, 20, 32, 56]
result = reduce(lambda init, item: init + item, nums, 0)
print(result)

练习2:求nums中所有元素的乘积 -> 480 => 1 * 2 * 3 * 8 * 10

nums = [2, 3, 8, 10]
result = reduce(lambda init, item: init * item, nums, 1)
print(result)

练习3:和并nums中的数据 -> ‘23810’ -> int(‘23810’) =>’’ + str(2) + str(3) + str(8) + str(10)

nums = [2, 3, 8, 10]
result = reduce(lambda init, item: init + str(item), nums, '')
print(result, int(result))

练习4:将names中的元素合并 -> ‘小张李老’

# '' + '小' + '张' + '李' + '老'
# '' + '小明'[0] + '张三'[0] + '李四'[0] + '老王'[0]
names = ['小明', '张三', '李四', '老王']
result = reduce(lambda init, item: init + item[0], names, '')
print(result)

练习5:将nums中所有的元素按照数值大小求和 -> 40.0

# 0 + float(10) + float('12') + float(12.5) + float('5.5')
nums = [10, '12', 12.5, '5.5']
result = reduce(lambda init, item: init + float(item), nums, 0)
print(result)

练习6:将nums中所有的数字数据求和 -> 12 + 100 + 10.5 -> 122.5

nums = [12, 'abc', '12.5', 100, 10.5]

# 方法一
# nums = [12, 100, 10.5]  -> 0 + 12 + 100 + 10.5
result = reduce(lambda init, item: init + item, [x for x in nums if type(x) in (int, float)], 0)
print(result)

# 方法二
# [12, 'abc', '12.5', 100, 10.5]  -> 0 + 12 + 0 + 0 + 100 + 10.5
result = reduce(lambda init, item: init + (item if type(item) in (int, float) else 0), nums, 0)
print(result)

练习7:已知一个学生列表

students = [
    {'name': '小明', 'age': 18, 'math': 90, 'chinese': 85, 'English': 60},
    {'name': 'stu1', 'age': 22, 'math': 83, 'chinese': 80, 'English': 30},
    {'name': 'stu2', 'age': 30, 'math': 67, 'chinese': 93, 'English': 87},
    {'name': 'stu3', 'age': 19, 'math': 55, 'chinese': 76, 'English': 69},
    {'name': 'stu4', 'age': 17, 'math': 79, 'chinese': 80, 'English': 90}
]
# 1) 求班级语文成绩的平均成绩 - reduce
total_chinese = reduce(lambda init, item: init + item['chinese'], students, 0)
print('语文平均分:', total_chinese / len(students))

# 2)按照学生的平均分对列表从大到小排序 - sored、sort
# students.sort(key=lambda stu: stu['math'] + stu['chinese'] + stu['English'], reverse=True)
# print(students)

new_students = sorted(students, key=lambda stu: stu['math'] + stu['chinese'] + stu['English'], reverse=True)
print(new_students)

# 3)将address里面的数据依次关联到每个学生中 - map
address = ['重庆', '成都', '北京', '昆明', '深圳']


def temp(stu, addr):
    stu['address'] = addr
    return stu


new_students = list(map(temp, students, address))
print(new_students)

迭代器

1. 什么是迭代器(iter)

迭代器是容器型数据类型 - 可以遍历,也可以转换成列表或者元组等
打印迭代器无法查看元素;无法统计迭代器中元素的个数;
如果要获取迭代器的元素,必须将元素从迭代器中取出来,而且元素一旦取出,这个元素在迭代器中就不存在,也无法重新添加。

2.怎么创建迭代器

方法一:用iter将其他的序列转换成迭代器(任何序列都可以转化成迭代器)
方法二:创建一个生成器
iter1 = iter(‘hello’)
iter2 = iter([10, 20, 30])
iter3 = iter({‘name’: ‘张三’, ‘age’: 18})
iter4 = iter({100, 200, 300})

迭代器打印无法查看元素
print(iter1) # <str_iterator object at 0x1074358e0>
print(iter2) # <list_iterator object at 0x1070138b0>

迭代器不能统计元素个数
print(len(iter1)) # TypeError: object of type ‘str_iterator’ has no len()

3.获取迭代器的元素

不管以什么样的方式得到了迭代器中的元素,那么被获取到的元素一定会从迭代器中消失
1)获取单个元素
next(迭代器) - 获取当前迭代器最上面的那个元素

2)遍历
for 变量 in 迭代器:
循环体

iter1 = iter('hello')
print(next(iter1))      # h
print(next(iter1))      # e
print(next(iter1))      # l
print(next(iter1))      # l
print(next(iter1))      # o
# print(next(iter1))      # 报错:StopIteration

iter2 = iter([10, 20, 30])
for x in iter2:
    print(f'x:{x}')   # h  e  l  l  o

# print(next(iter2))      # 报错:StopIteration

iter3 = iter({'name': '张三', 'age': 18, 'gender': '男'})
print(next(iter3))      # 'name'
for x in iter3:
    print(f'x:{x}')

iter1 = iter('hello')
print(list(iter1))    # ['h', 'e', 'l', 'l', 'o']
# print(next(iter1))    # 报错:StopIteration

生成器

1. 什么是生成器

生成器是一种容器(保存不是多个数据,而且产生多个数据的算法) - 可以遍历,也可以转换成列表、元组等
生成器具备迭代器所有的特点:打印无法看到元素、无法统计个数、元素一旦获取对应的元素就会从生成器中消失

2.怎么创建生成器

调用一个带有yield关键字的函数就可以得到一个生成器。
如果调用的是普通函数,调用函数的时候会执行函数体,并且获取函数返回值;
如果调用的函数的函数体中有yield,调用函数的时候不会执行函数体,也不会获取函数返回值,得到的是一个生成器对象。

def func1():
    print('=======')
    print('+++++++')
    print('--------')
    yield
    # if False:
    #     yield
    return 100


result = func1()
print(result)       # <generator object func1 at 0x1031f6b30>

3. 控制生成器产生数据的个数和值

生成器能产生多少个数据,能产生哪些数据由创建生成器的时候调用的那个函数的函数体,在执行的时候会遇到几次yield以及每次遇到yield的时候,yield后面的值来决定。

def func1():
    yield 100
    yield 200
    if 10 > 20:
        yield 400
    return 300
    yield 300


gen1 = func1()
print(list(gen1))       # [100, 200]
# print(next(gen1))       # 报错: StopIteration

练习: 写一个生成器可以创建3个元素,分别是100、200和300

def create_num():
    # yield 100
    # yield 200
    # yield 300
    for x in range(100, 301, 100):
        yield x


gen2 = create_num()
print(next(gen2))
print(next(gen2))
print(next(gen2))
# print(next(gen2))     # 报错:StopIteration


# print(next(create_num()))       # 100
# print(next(create_num()))       # 100
# print(next(create_num()))       # 100

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

def func2():
    print('============')
    yield 100
    print('+++++++++++')
    yield 200
    print('----------')
    yield 300
    print('end')
    return 100
    print('**********')


gen3 = func2()
print(gen3)
print('-----------第1次-------------')
print('next:', next(gen3))

print('-----------第2次-------------')
print('next:', next(gen3))

print('-----------第3次-------------')
print('next:', next(gen3))

print('-----------第4次-------------')
# print('next:', next(gen3))

练习1:写一个函数可以创建Python学生的学号的生成器

# 'python001'、'python002'、.... 'python999'
def num_creater():
    for x in range(1, 1000):
        yield f'python{x:0>3}'


gen_num = num_creater()
print(next(gen_num))
print(next(gen_num))
print(next(gen_num))
for _ in range(5):
    print(next(gen_num))

练习2:写一个函数可以创建指定学科的学生的学号的生成器

# python   ->  'python001'、'python002'、.... 'python999'
# java     ->   'java001'、'java002'、.... 'java999'
def num_creater2(subject: str):
    for x in range(1, 1000):
        yield f'{subject}{x:0>3}'

java_nums = num_creater2('java')
python_nums = num_creater2('python')

print(next(java_nums))

print(next(python_nums))
print(next(python_nums))

print(next(java_nums))
print(next(java_nums))

h5_nums = num_creater2('h5')

模块的使用

1. 什么是模块

一个py文件就是一个模块,模块名就是py文件的文件名

2. 怎么在一个模块中使用另外一个模块中的内容

前提:只有模块名字是标识符并且不是关键的模块才能被其他模块使用
原则:先导入才能用

3. 模块的分类

系统模块 - Python环境中自带的py文件
自定义模块 - 程序员自己创建的py文件

4. 怎么导入模块

  1. import 模块名 - 导入指定模块,导入后可以通过’模块名.'的方式使用这个模块中所有的全局变量
  2. from 模块名 import 变量1, 变量2,… - 导入指定模块,导入后可以直接使用对应的变量
  3. from 模块名 import * - 导入指定模块,导入后可以直接使用模块中所有的全局变量
  4. 重命名
    import 模块名 as 新模块名 - 对模块重命名
    from 模块名 import 变量1 as 新变量1, 变量2,… - 对变量重命名
# 导入方式1
# import test
# print(test.a)
# print(test.name)
# test.func1()

# import functools
# functools.reduce()

# 导入方式2
# from test import a, func1
# print(a)
# func1()
# # print(name)           # NameError: name 'name' is not defined

# from functools import reduce
# reduce()

# 导入方式3
# from test import *
# print(a)
# print(name)
# func1()

# 模块重命名
# import test as ts
# print(ts.a)
# print(ts.name)
# ts.func1()

# import test as ts
# test = '好好学习!'
# print(test[-1])
# ts.func1()

# from test import a, name as t_name
# name = '小明'
# print(name)
# print(t_name)
#
# print(a)

# import math
# print(math.factorial(10))

# from math import factorial
# print(factorial(10))

from math import factorial as fac
print(fac(10))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值