018.Python迭代器以及map和reduce函数
Posted 战五渣
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了018.Python迭代器以及map和reduce函数相关的知识,希望对你有一定的参考价值。
一 迭代器
- 能被next进行调用,并且不断返回下一个值的对象
- 特征:迭代器会生成惰性序列,它通过计算把值依次的返回,一边循环一边计算而不是一次性得到所有数据
- 优点:需要数据的时候,一次取一个,可以大大节省内存空间.而不是一股脑的把所有数据放进内存.
- 可以遍历无限量的数据
- next调用迭代器时,方向是单向不可逆的.
1.1 可迭代性对象
__iter__ 如果这个数据类型含有__iter__ 方法 我们就说他是可迭代对象
dir 获取当前数据内置的方法和属性.
setvar = {1,2,"abc",54,"dd"} for i in setvar: print(i) lst = dir(setvar) print(lst) print("__iter__" in lst)
执行
dd 1 2 54 abc [\'__and__\', \'__class__\', \'__contains__\', \'__delattr__\', \'__dir__\', \'__doc__\', \'__eq__\', \'__format__\',
\'__ge__\', \'__getattribute__\', \'__gt__\', \'__hash__\', \'__iand__\', \'__init__\', \'__init_subclass__\',
\'__ior__\', \'__isub__\', \'__iter__\', \'__ixor__\', \'__le__\', \'__len__\', \'__lt__\', \'__ne__\', \'__new__\',
\'__or__\', \'__rand__\', \'__reduce__\', \'__reduce_ex__\', \'__repr__\', \'__ror__\', \'__rsub__\', \'__rxor__\',
\'__setattr__\', \'__sizeof__\', \'__str__\', \'__sub__\', \'__subclasshook__\', \'__xor__\', \'add\', \'clear\',
\'copy\', \'difference\', \'difference_update\', \'discard\', \'intersection\', \'intersection_update\',
\'isdisjoint\', \'issubset\', \'issuperset\', \'pop\', \'remove\', \'symmetric_difference\', \'symmetric_difference_update\',
\'union\', \'update\'] True
1.2 迭代器
可迭代型数据:可以遍历的数据 for 循环在遍历集合的时候,在底层用next方法实现的集合的调用
区别
可迭代对象 -> 迭代器 不可直接调用 -> 可直接调用的过程
如何变成迭代器
(1) iter (2)__iter__() #这两个方法可以变成迭代器
如何遍历迭代器?
(1) next (2)__next__()
如何判断迭代器?
__iter__ __next__ 如果含有这两个方法,就说他是迭代器
可迭代对象不一定是迭代器,迭代器一定是可迭代对象
setvar = {1,2,"abc",54,"dd"} it = iter(setvar) lst = dir(it) print(lst) print(\'__iter__\' in lst and \'__next__\' in lst) res = next(it) print(res) res = next(it) print(res) res = next(it) print(res) res = next(it) print(res) res = next(it) print(res)
执行
[root@node10 python]# python3 test.py t test.py [\'__class__\', \'__delattr__\', \'__dir__\', \'__doc__\', \'__eq__\', \'__format__\', \'__ge__\', \'__getattribute__\', \'__gt__\', \'__hash__\', \'__init__\', \'__init_subclass__\', \'__iter__\', \'__le__\', \'__length_hint__\', \'__lt__\', \'__ne__\', \'__new__\', \'__next__\', \'__reduce__\', \'__reduce_ex__\', \'__repr__\', \'__setattr__\', \'__sizeof__\', \'__str__\', \'__subclasshook__\'] True 1 2 dd 54 abc
1.3 判断是否是可迭代对象或者迭代器
- from .. import 从哪个模块 ... 引入 ...东西
- 从collections模块 引入 Iterator类型(迭代器类型) Iterable(可迭代对象)
判断集合的迭代属性
from collections import Iterator,Iterable # 判断集合的迭代属性 setvar = {1,2,"abc",54,"dd"} res = isinstance(setvar,Iterable) print(res) res = isinstance(setvar,Iterator) print(res)
执行
[root@node10 python]# python3 test.py t test.py True False
判断range对象的迭代属性
from collections import Iterator,Iterable # 1.判断集合的迭代属性 setvar = {1,2,"abc",54,"dd"} print(isinstance(range(10),Iterable)) # True print(isinstance(range(10),Iterator)) # False #使用iter方法,可以把一个可迭代对向变成一个迭代器 it = iter(range(10)) res = next(it) print(res) res = next(it) print(res)
执行
[root@node10 python]# python3 test.py t test.py True False 0 1
遍历迭代器
it = iter(range(10)) for i in it: print(i)
执行
[root@node10 python]# python3 test.py 0 1 2 3 4 5 6 7 8 9
1.4 迭代器的越界现象错误
it = iter(range(10)) for i in it: print(i)res = next(it)print(res)
执行
[root@node10 python]# python3 test.py 0 1 2 3 4 5 6 7 8 9 Traceback (most recent call last): File "test.py", line 4, in <module> res = next(it) StopIteration
StopIteration 是迭代器的越界现象错误,是因为没有值了
1.5 重置迭代器
it = iter(range(10)) # for i in it: # print(i) # 使用for 和 next 搭配来遍历迭代器for i in range(3): res = next(it) print(res)
执行
[root@node10 python]# python3 test.py 0 1 2
二 高阶函数
- 能够把函数当成参数传递的就是高阶函数 (map reduce sorted filter)
2.1 map(func,iterable)
功能:把iterable里面的数据一个一个的拿出来,扔到func当中进行处理,然后把处理之后的结果放到迭代器当中,最终返回迭代器
参数:
func:自定义函数 或者 内置函数
iterable:可迭代对象(常用:容器类型数据,range对象,迭代器)
返回值:
迭代器
["1","2","3","4"] 变成整型 [1,2,3,4]
listvar = ["1","2","3","4"] lst = [] for i in listvar: print(i,type(i)) #打印数值并输出类型 res = int(i) #强制转换成整型 lst.append(res) #塞进空列表 print(lst)
执行
[root@node10 python]# python3 test.py 1 <class \'str\'> 2 <class \'str\'> 3 <class \'str\'> 4 <class \'str\'> [1, 2, 3, 4]
使用map实现
- 每次从listvar当中拿出一个值 ,
- 放到int函数当中进行强转,处理后的结果扔到迭代器当中
- 依次类推,直到所有数据拿完为止.
listvar = ["1","2","3","4"] from collections import Iterator,Iterable it = map(int,listvar) print(isinstance(it,Iterator)) print(isinstance(it,Iterable)) #next取值 res = next(it) print(res) res = next(it) print(res) res = next(it) print(res) res = next(it) print(res)
执行
[root@node10 python]# python3 test.py True True 1 2 3 4
使用for循环取值
listvar = ["1","2","3","4"] from collections import Iterator,Iterable it = map(int,listvar) print(isinstance(it,Iterator)) print(isinstance(it,Iterable)) for i in it: print(i)
执行
[root@node10 python]# python3 test.py True True 1 2 3 4
list类型强转
使用list强转迭代器可以瞬间拿到迭代器中所有数据
listvar = ["1","2","3","4"] from collections import Iterator,Iterable it = map(int,listvar) lst = list(it) print(lst)
执行
[root@node10 python]# python3 test.py [1, 2, 3, 4]
[“5”,“4”,“9”,“9"] 转换为5499
使用字符串拼接
lst=["5","4","9","9"] res=\'\'.join(lst) print(res)
执行
[root@node10 python]# python3 test.py 5499
[1,2,3,4] 转为[2,4,6,8]
lst = [] for i in [1,2,3,4]: res = i * 2 lst.append(res) print(lst)
使用map
如果使用自定义方法,切记要加上return 返回值
from collections import Iterator,Iterable lst = [1,2,3,4] def func(n): return n * 2 it = map(func,lst) print(isinstance(it,Iterator)) print(list(it))
执行
[root@node10 python]# python3 test.py True [2, 4, 6, 8]
{97:\'a\',98:\'b\',99:\'c\'} [\'a\',\'b\',\'c\'] =>[97,98,99]
打印出键
dic = {97:"a",98:"b",99:"c"} for i in dic: print (i)
执行
[root@node10 python]# python3 test.py 97 98 99
使用item打印键值对,并反转
dic = {97:"a",98:"b",99:"c"} dic2={} for a,b in dic.items(): dic2[b] =a print(dic2)
执行
[root@node10 python]# python3 test.py {\'a\': 97, \'b\': 98, \'c\': 99}
正常顺序
使用map
lst = [\'a\',\'b\',\'c\'] def func(n): dic = {97:"a",98:"b",99:"c"} dic2={} for a,b in dic.items(): dic2[b] =a return dic2[n] it = map(func,lst) #func是自定义函数,lst是可迭代对象 print (list(it)) #list(it)强制list转换
执行
root@node10 python]# python3 test.py [97, 98, 99]
2.2 reduce函数
reduce(func,iterable)
功能:
计算
首先把iterable 当中的两个值拿到func当中进行运算,计算的结果在和iterable中的第三个值
拿到func中计算,依次类推.返回最终的结果
参数:
func 自定义函数 或者 内置函数
iterable 可迭代对象(常用:容器类型数据 range对象 迭代器)
返回值:
最终的计算结果
[5,4,9,9] 转换为5499
使用上个方式不能成功
lst=[5,4,9,9] res=\'\'.join(lst) print(res)
执行报错
先取出转为字符串类型,合并在转
strvar = \'\' for i in [5,4,9,9]: strvar += str(i) print(strvar,type(strvar)) print(int(strvar),type(int(strvar)))
执行
[root@node10 python]# python3 test.py 5499 <class \'str\'> 5499 <class \'int\'>
使用reduce实现
逻辑实现
5*10 +4 = 54 54*10+9 = 549 549*10+9 = 5499
普通示例
lst = [5,4,9,9] it = iter(lst) res1 = next(it) res2 = next(it) total = res1 * 10 + res2 print(total) for i in it: #54 # 54 * 10 + 9 = 549 # 549 * 10 + 9 = 5499 total = total * 10 + i print(total)
执行
[root@node10 python]# python3 test.py 54 5499
reduce实现
from functools import reduce def func(x,y): return x*10 + y lst = [5,4,9,9] res = reduce(func,lst) print(res)
执行
[root@node10 python]# python3 test.py 5499
实现过程
先把列表中5和4拿出来放到func函数中用x,和 y来接收参数 x*10+y => 5*10+4 =54 第二次 拿54 和 9两个值扔到func当中进行运算 x*10+y => 54 * 10 + 9 => 549 第三次 拿549 和 9 两个值扔到func当中进行运算 x*10+y => 549 * 10 + 9 => 5499 到此所有计算完毕 ,返回5499
"534" => 534 不使用int强转实现
from functools import reduce strvar = "534" def func(x,y): return x*10 + y 这里变成字符串拼接,而不是一个数字计算 res = reduce(func,list(strvar)) print(res)
执行
[root@node10 python]# python3 test.py 555555555535555555555355555555553555555555535555555555355555555553555555555535555555555355555555553555555555534
正确方式
from functools import reduce strvar = "534" def func(x,y): return x*10 + y # res = reduce(func,list(strvar)) # print(res) error def func2(n): dic = {\'0\':0,\'1\':1,\'2\':2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9} #定义一个字典,定义字符串和对应键值对 return dic[n] #遇到对应字符串的键,返回该键的值 it = map(func2,"534") #相当于吧字符串迭代取出,放进func执行 # print(list(it)) #这个使用list强转就是[5,3,4] res = reduce(func,it) #取出it的迭代数据,使用func进行计算 print(res)
执行
[root@node10 python]# python3 test.py 534
以上是关于018.Python迭代器以及map和reduce函数的主要内容,如果未能解决你的问题,请参考以下文章
map,reduce,filter的总结(reduce还有点不懂,一会自己再看看)
python基础之map/reduce/filter/sorted