day13. 迭代器与高阶函数
一、迭代器
"""
能被next调用,并不断返回下一个值的对象,叫做迭代器(对象)
概念:
迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续的,
单纯的重复并不是迭代
特征:
并不依赖索引,而通过next指针迭代所有数据,一次只取一个值,大大节省空间
"""
1、可迭代对象
setvar = {"a","b","c","d"}
for i in setvar:
print(i)
# dir 获取当前类型对象中的所有成员
"""__iter__ 方法用来判断是否是可迭代性数据"""
lst = dir(setvar)
print(dir(""))
res = "__iter__" in dir(setvar)
print(res)
2、迭代器
"""
for 循环能够遍历一切可迭代性数据的原因在于,底层调用了迭代器,通过next方法中的指针实现数据的获取
可迭代对象 -> 迭代器 不能够被next直接调用 -> 可以被next直接调用的过程 如果是一个可迭代对象不一定是迭代器
但如果是一个迭代器就一定是一个可迭代对象
"""
2.1、如何来定义一个迭代器
setvar = {"a","b","c","d"}
it = iter(setvar)
print(it)
2.2、如何来判断一个迭代器
print(dir(it))
res = "__iter__" in dir(it) and "__next__" in dir(it)
print(res)
2.3、如何来调用一个迭代器
"""next在调用迭代器中的数据时,是单向不可逆,一条路走到黑的过程"""
res = next(it)
print(res)
res = next(it)
print(res)
res = next(it)
print(res)
res = next(it)
print(res)
"""
# StopIteration 报错 停止迭代
res = next(it)
print(res)
"""
3、重置迭代器
it = iter(setvar)
res = next(it)
print(res)
4、使用其他方式判断迭代器或者可迭代对象
"""Iterator 迭代器 Iterable 可迭代对象"""
# from ... 从哪里 import 引入 ...
from collections import Iterator,Iterable
# from collections.abc import Iterator,Iterable python3.7
res = isinstance(it,Iterator)
print(res)
res = isinstance(it,Iterable)
print(res)
5、使用其他方式调用迭代器中的数据
# 1. for 循环
print("<=>")
for i in it:
print(i) # 2. for + next
print("<=>")
lst = [1,2,3,4,5,6,7,7,8,9,10]
it = iter(lst)
for i in range(10):
res = next(it)
print(res) print(next(it))
print(next(it))
6、总结
'''
迭代器: 迭代器(Iterator)可以看做是一个特殊的对象,每次调用该对象是会返回自身的下一个元素,一个迭代器对象必须是定义了__iter__()方法和next()方法的对象 为什么要有迭代器:
序列类型字符串、列表、元组都有下标,用下标访问没问题。但是非序列类型像字典、集合、文件对象就不能用下标,for循环就是基于迭代器协议
提供了一个统一的可以遍历所有对象的方法。即在遍历前,先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议去实现循环访问
这样所有的对象都可以通过for循环访问了。循环结束,捕捉异常,循环结束。这种方式不依赖与索引 可迭代对象: 可迭代对象是指内置有__iter__ 方法的对象,即 obj.__iter__ 字符串、元组、列表、字典都可以进行迭代 'kxq'.__iter__ open('kxq.txt'.__iter__) 迭代器对象 可迭代对象执行obj.__iter__()得到的结果就是迭代器对象 迭代器对象指内置有 __iter__ 、 __next__ 方法的对象 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象
'''
i = [1, 2, 3]
iter_l = i.__iter__() # 得到迭代器对象,
print(iter_l.__next__()) # 与 next(iter_l)相同
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())# 抛出异常 StopIteration # iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误;
6.1、for 循环原理
i = [1, 2, 3] for x in i:
print(x) # 原理
# 1.执行i.__iter__() 方法,得到一个迭代器对象 iter_i
# 2.执行 iter_i.__next__()方法,将得到的值赋值给x,进入循环体
# 重复2,捕捉StopIteration异常,循环结束
6.2、优缺点
# 缺点: 它的特性决定了它只能往前,不能后退 # 有点:节省内存,惰性计算,不依赖与索引
二、map函数
"""
map(func,Iterable)
功能:处理数据
把Iterable中的数据一个一个拿出来,扔到func函数中做处理
把处理之后的结果放到迭代器当中,最后返回迭代器
参数:
func : 自定义函数 或 内置函数
Iterable : 可迭代性数据(容器类型数据 range对象 迭代器)
返回值:
迭代器
"""
1、lst = ["1","2","3","4"] 转换为 [1,2,3,4]
lst = ["","","",""]
# 常规写法
lst_new = []
for i in lst:
lst_new.append(int(i))
print(lst_new) # map改造
it = map(int,lst) """
# 代码解析:
先把"1" 扔到int当中做处理,将强转后的结果扔到迭代器中
然后把"2" 扔到int当中做处理,将强转后的结果扔到迭代器中
然后把"3" 扔到int当中做处理,将强转后的结果扔到迭代器中
然后把"4" 扔到int当中做处理,将强转后的结果扔到迭代器中
最终返回迭代器
"""
1.1、获取迭代器中的数据
# 1.next
res = next(it)
print(res)
res = next(it)
print(res)
res = next(it)
print(res)
res = next(it)
print(res)
# 2.for
for i in it:
print(i) # 3.for + next
for i in range(4):
res = next(it)
print(res) # 4.list强转
print(list(it))
2、[1,2,3,4] 转换为 [2,8,24,64]
lst = [1,2,3,4]
'''
1 * 2^1 = 2
2 * 2^2 =8
3 * 2^3 =24
4 * 2^4 =64
'''
lst_new = []
for i in lst:
res = i << i
lst_new.append(res)
print(lst_new)
# map改造
'''参数和返回值return一定要写'''
def func(n):
return n << n lst = [1,2,3,4]
it = map(func,lst)
print(list(it))
# lambda + map
it = map(lambda n : n << n , lst)
print(list(it))
3、{"a":97,"b":98,"c":99} 转换为 [97,98,99]
dic = {"a":97,"b":98,"c":99}
def func(lst):
lst_new = []
# 遍历列表
for i in lst:
# 通过键取值
res = dic[i]
# 把值追加到新的列表中
lst_new.append(res)
# 返回新列表
return lst_new # [97,98,99]
res = func(lst = ["a","b","c"])
print(res)
# 将键值对反转
dic = {97:"a",98:"b",99:"c"}
dic_new = {}
for k,v in dic.items():
dic_new[v] = k
print(dic_new) lst = ["a","b","c"]
lst_new = []
# 遍历列表
for i in lst:
# 通过键取值
res = dic_new[i]
# 把值追加到新的列表中
lst_new.append(res)
# 返回新列表
print(lst_new)
# map改造
def func(n):
# 原字典
dic = {97:"a",98:"b",99:"c"}
# 新字典
dic_new = {}
# 遍历原字典
for k,v in dic.items():
# 更换键值对
dic_new[v] = k
print(dic_new) # {'a': 97, 'b': 98, 'c': 99}
# 通过键来获取值
return dic_new[n] lst = ["a","b","c"]
it = map(func,lst)
print(list(it))
三、filter函数
"""
filter(func,iterable)
功能: 过滤数据
return True 当前这个数据保留
return False 当前这个数据舍弃
参数:
func : 自定义函数
iterable : 可迭代型数据(容器类型数据,range对象,迭代器)
返回值:
迭代器
"""
lst = [1,2,3,4,5,6,7,8,9,10]
# 常规写法
lst_new = []
for i in lst:
if i % 2 == 0:
lst_new.append(i) print(lst_new)
# filter改写
def func(i):
if i % 2 == 0:
return True
else:
return False it = filter(func,lst)
# (1) next
res = next(it)
print(res) # (2) for
print("<====>")
for i in it:
print(i) # (3) for + next
it = filter(func,lst)
for i in range(3):
res = next(it)
print(res) # (4) list强转
res = list(it)
print(res)
# filter + lambda 改写
it = filter(lambda i : True if i % 2 == 0 else False , lst )
print(list(it))
四、reduce函数
"""
reduce(func,iterable)
功能:计算数据
先把iterable中的前两个值拿出来,扔到func当中做运算,
把计算的结果和iterable中的第三个元素在扔到func当中做运算,
再把结果算出来,和第四个元素做运算,以此类推
直到所有结果运算完毕.返回该结果
参数:
func : 自定义函数
iterable : 可迭代型数据(容器类型数据,range对象,迭代器)
返回值:
计算之后的结果
"""
1、lst = [5,4,8,8] 转换 整型5488
# 常规写法
# 方法一
strvar = ""
for i in lst:
strvar += str(i)
print(strvar , type(strvar))
res = int(strvar)
print(res , type(res))
from functools import reduce
from collections import Iterator,Iterable
lst = [5,4,8,8]
it = iter(lst)
print(isinstance(it , Iterator))
print(isinstance(it , Iterable)) num1 = next(it)
num2 = next(it)
print(num1,num2)
num = num1 * 10 + num2
print(num) # for i in it:
num = num * 10 + i # 54 * 10 + 8 => 548
print(num, type(num))
# reduce 改造
def func(x,y):
return x*10 + y
lst = [5,4,8,8]
res = reduce(func,lst)
print(res , type(res))
"""
# 代码解析:
先拿出5和4两个元素,扔到func当中做运算,结果是54
在拿54和8两个元素,扔到func当中做运算,结果548
在拿548和8两个元素,扔到func当中做运算,结果5488
返回最终的结果: 5488 程序结束
"""
# 使用reduce + lambda改造
res = reduce(lambda x,y:x*10+y,lst)
print(res)
2、"789" => 789 禁止使用int强转
# "789" -> 数字7 数字8 数字9
def func1(x,y):
return x*10 + y
def func2(n):
dic = {"":0,"":1,"":2,"":3,"":4,"":5,"":6,"":7,"":8,"":9}
return dic[n]
it = map(func2,"") # [7,8,9]
res = reduce(func1,it)
print(res,type(res))
五、sorted函数
"""
sorted(iterable,key=函数,reverse=False)
功能:排序
参数:
iterable:可迭代型数据(容器类型数据,range对象,迭代器)
key :指定自定义函数或内置函数
reverse :代表升序或者降序 , 默认是升序(从小到大排序) reverse=False
返回值:
排序后的结果
"""
# 1.默认是从小到大排序
lst = [1,2,3,4,5,-90,-4,-1,100]
res = sorted(lst)
print(res) # 2.reverse 从大到小排序
res = sorted(lst,reverse=True)
print(res) # 3.指定函数进行排序
# 按照绝对值排序 abs
lst = [-10,-1,3,5]
res = sorted(lst,key=abs)
"""
-1 => abs(-1) => 1
3 => abs(3) => 3
5 => abs(5) => 5
-10 => abs(-10) => 10
[-1, 3, 5, -10]
"""
print(res)
1、使用自定义函数进行排序
lst = [19,21,38,43,55]
def func(n):
return n % 10
lst = sorted(lst,key=func)
print(lst)
"""
21 => n % 10 => 1
43 => n % 10 => 3
55 => n % 10 => 5
38 => n % 10 => 8
19 => n % 10 => 9 21 43 55 38 19
"""
2、可迭代类型数据排序
# 字符串
container = "eadc"
# 列表
container = [19,21,38,43,55]
# 元组
container = (19,21,38,43,55)
# 集合
container = {19,21,38,43,55}
# 字典 (排序的是字典的键)
container = {"c":3,"a":1,"b":2}
container = {"王闻":3,"高云峰":2}
print("<===>")
res = sorted(container)
print(res)
3、sorted 和 sort 之间的区别
# (1) sorted可以排序一切容器类型数据, sort只能排列表
# (2) sorted返回的是新列表,sort是基于原有的列表进行修改
# (3) 推荐使用sorted
六、练习
"""
# 1.用map来处理字符串列表,把列表中所有人都变成 leader ,比方alex_leader
name = ['oldboy', 'alex', 'wusir'] # 2.用map来处理下述 listvar ,要求得到新列表,每个元素名字加后面加_leader
listvar = [{'name':'alex'},{'name':'wusir'}] # 3.用filter来处理,得到股票价格大于20的股票名字
shares={
'IBM':36.6,
'Lenovo':23.2,
'oldboy':21.2,
'ocean':10.2,
} # 4.有下面字典:
portfolio=[
{'name':'IBM','shares':100,'price':91.1},
{'name':'AAPL','shares':20,'price':54.0},
{'name':'FB','shares':200,'price':21.09},
{'name':'HPQ','shares':35,'price':31.75},
{'name':'YHOO','shares':45,'price':16.35},
{'name':'ACME','shares':75,'price':115.65}
]
# a.获取购买每只股票的总价格(乘积),迭代器中[9110.0, 1080.0 ,......]
# b.用filter过滤出price大于100的股票。 # 5.将listvar 按照列表中的每个字典的values大小进行排序,形成一个新的列表。
listvar = [
{'sales_volumn': 0},
{'sales_volumn': 108},
{'sales_volumn': 337},
{'sales_volumn': 475},
{'sales_volumn': 396},
{'sales_volumn': 172},
{'sales_volumn': 9},
{'sales_volumn': 58},
{'sales_volumn': 272},
{'sales_volumn': 456},
{'sales_volumn': 440},
{'sales_volumn': 239}
]
"""

def func(n):
return n+"_leader" name = ['oldboy', 'alex', 'wusir']
it = map(func,name)
print(list(it)) # lambda
it = map(lambda n : n+"_leader",name)
print(list(it))
1

def func(n):
print(n) # {'name': 'alex'}
return n["name"] + "_leader" listvar = [{'name':'alex'},{'name':'wusir'}]
it = map(func,listvar)
print(list(it)) # lambda
it = map(lambda n : n["name"] + "_leader" , listvar)
print(list(it))
2

shares={
'IBM':36.6,
'Lenovo':23.2,
'oldboy':21.2,
'ocean':10.2,
}
def func(n):
return shares[n] > 20
it = filter(func,shares)
print(list(it))
# lambda
it = filter(lambda n : shares[n] > 20 , shares)
print(list(it))
3

portfolio=[
{'name':'IBM','shares':100,'price':91.1},
{'name':'AAPL','shares':20,'price':54.0},
{'name':'FB','shares':200,'price':21.09},
{'name':'HPQ','shares':35,'price':31.75},
{'name':'YHOO','shares':45,'price':16.35},
{'name':'ACME','shares':75,'price':115.65}
]
# a.获取购买每只股票的总价格(乘积),迭代器中[9110.0, 1080.0 ,......]
def func(n):
return n["shares"] * n["price"] it = map(func,portfolio)
print("<====>")
print(list(it))
4 (a)

portfolio=[
{'name':'IBM','shares':100,'price':91.1},
{'name':'AAPL','shares':20,'price':54.0},
{'name':'FB','shares':200,'price':21.09},
{'name':'HPQ','shares':35,'price':31.75},
{'name':'YHOO','shares':45,'price':16.35},
{'name':'ACME','shares':75,'price':115.65}
] # b.用filter过滤出price大于100的股票
def func(n):
return n["price"] > 100 it = filter(func,portfolio)
print(list(it))
4 (b)

# 5.将listvar 按照列表中的每个字典的values大小进行排序,形成一个新的列表。
listvar = [
{'sales_volumn': 0},
{'sales_volumn': 108},
{'sales_volumn': 337},
{'sales_volumn': 475},
{'sales_volumn': 396},
{'sales_volumn': 172},
{'sales_volumn': 9},
{'sales_volumn': 58},
{'sales_volumn': 272},
{'sales_volumn': 456},
{'sales_volumn': 440},
{'sales_volumn': 239}
]
def func(n):
return n["sales_volumn"]
print("<===>")
lst = sorted(listvar,key=func)
print(lst)
5
day13. 迭代器与高阶函数的更多相关文章
- Python 基础之匿名函数 迭代器和高阶函数
一.匿名函数 lambda表达式 用一句话来表达只有返回值的函数,叫匿名函数特点:简洁方便语法:lambda 参数: 返回值 1.不带有参数的lambda表达式 def func(): retu ...
- Learn day5 迭代器\生成器\高阶函数\推导式\内置函数\模块(math.time)
1.迭代器 # ### 迭代器 """能被next调用,并不断返回下一个值的对象""" """ 特征:迭代器会 ...
- Python学习笔记【第六篇】:迭代器、生成器、高阶函数、装饰器
迭代器 迭代器是访问集合元素的一种方式,迭代器从对象的第一个元素开始访问,知道所有元素被访问完成.迭代器只能往前访问,不能通过索引访问. 类型内部使用__iter__()方法转为迭代器,使用__nex ...
- day11-Python运维开发基础(迭代器与可迭代对象、高阶函数)
1. 迭代器与可迭代对象 # ### 迭代器 """ 迭代器: 能被next方法调用,并且不断返回下一个值的对象,是迭代器(对象) 特征:迭代器会生成惰性序列,它通过计算 ...
- 08 . Python3高阶函数之迭代器、装饰器
Python3高阶函数之迭代器.装饰器 列表生成式 推导式就是构建比较有规律的列表,生成器. 孩子,我现在有个需求,看列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],我要求你把列表里 ...
- 高阶函数,柯里化,sort排序
高阶函数概念 first class object: 函数在python中时一等公民. 函数也是对象,可调用的对象. 函数可以作为普通变量,参数,返回值等等. 高阶函数: ...
- Python函数篇(二)之递归函数、匿名函数及高阶函数
1.全局变量和局部变量 一般定义在程序的最开始的变量称为函数变量,在子程序中定义的变量称为局部变量,可以简单的理解为,无缩进的为全局变量,有缩进的是局部变量,全局变量的作用域是整个程序,而局部变量的作 ...
- Python函数篇(2)-递归函数、匿名函数及高阶函数
1.全局变量和局部变量 一般定义在程序的最开始的变量称为函数变量,在子程序中定义的变量称为局部变量,可以简单的理解为,无缩进的为全局变量,有缩进的是局部变量,全局变量的作用域是整个程序,而局部变量的作 ...
- python3 第二十章 - 函数式编程之Higher-order function(高阶函数)
什么是高阶函数?把函数作为参数传入或把函数做为结果值返回,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式.函数式编程的特点: 函数本身可以赋值给变量,赋值后变量为函数: 允许将函数本身 ...
随机推荐
- 不用破解版的 Navicat 了,几款免费且好用的 SQL 客户端送给你
我是风筝,公众号「古时的风筝」. 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面. 没别的意思,今天就是为了给你推荐几款 MySQL 客户端,这几款 ...
- java学习第四天7/9
一. 今天学习了一些算法: 求最小值,最大值,平均值 接着学了几种排序方法 1.冒泡排序 (1)逐一比较数组中响铃的两个元素,如果后面的数字小于前面的数字,就交换先后元素: (2)经过一个轮次的比较, ...
- 谈谈你对this的理解
this的指向不是在编写时确定的,而是在执行时确定的,同时,this不同的指向在于遵循了一定的规则. 1.默认情况下,指向全局,浏览器的话就是指向window 2.如果函数被调用的位置存在上下文,那么 ...
- 从 (a==1&&a==2&&a==3) 成立中看javascript的隐式类型转换
下面代码中 a 在什么情况下会打印 1? var a = ?; if(a == 1 && a == 2 && a == 3){ console.log(1); } 这个 ...
- java 面向对象(二十七):注解的使用
1. 注解的理解① jdk 5.0 新增的功能*② Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理.通过使用 Annotation, ...
- 数据可视化之powerBI入门(十二)PowerBI中最重要的函数:CALCULATE
https://zhuanlan.zhihu.com/p/64382849 介绍DAX的时候,特别强调过一个重要的函数:CALCULATE,本文就来揭秘这个函数的计算原理以及它是如何影响上下文的. C ...
- java不需要递归列表转树形结构
有时候我们需要将列表结构的数据转成树形结构的数据 废话不多说直接上代码 基础类 `@Data public class TreeNode { private Long id; private Long ...
- ssh配置、vscode使用及常用扩展
1.ssh配置 1.1 进入命令行 win + r > cmd 1.2 输入如下代码直接回车即可生成ssh ssh-keygen -t rsa -C "xxx@qq.com&quo ...
- 题解 洛谷 P4098 【[HEOI2013]ALO 】
考虑原序列中的每一个值作为构成最终答案的那个次大值,那么其所在的合法区间最大时,其对答案的贡献最大. 一个值作为最大值时有两个合法的最大区间,一个是左边第二个比其大的位置和右边第一个比其大的位置构成的 ...
- NACOS安装和配置
安装包nacos-server-1.1.4.tar.gz 环境 JDK1.8 上传及解压 [root@centos7- ~ ]# mkdir -p /cslc/nacos #通过SFTP将安装包上传至 ...