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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM