函數進階· 第3篇《經常使用內置函數filter()、map()、zip(),怎麼用的呢?》

堅持原創輸出,點擊藍字關注我吧

做者:清菡
博客:oschina、雲+社區、知乎等各大平臺都有。python

因爲微信公衆號推送改成了信息流的形式,防止走丟,請給加個星標 ⭐,你就能夠第一時間接收到本公衆號的推送!微信

目錄

  • 1、filter()函數
    • 1.filter()過濾序列
    • 2.生成器、迭代器都是可迭代對象
  • 2、map()函數
  • 3、zip()函數
    • 1.什麼是 zip()函數
    • 2.zip()能夠快速建立字典

經常使用的內置函數:app

  • map()函數:會根據提供的函數對指定序列作映射。
  • filter()函數:函數用於過濾序列。
  • zip()函數:函數用於將可迭代的對象做爲參數,將對象中對應的元素打包成一個個元組。

1、filter()函數

1.filter()過濾序列

filter:過濾序列。第一參數是函數;第二參數是可迭代對象。函數

看看filter()這個內置函數的源碼:性能

class filter(object):
    """
    filter(function or None, iterable) --> filter object

    Return an iterator yielding those items of iterable for which function(item)
    is true. If function is None, return the items that are true.
    """
    def __getattribute__(self, *args, **kwargs): # real signature unknown
        """ Return getattr(self, name). """
        pass

    def __init__(self, function_or_None, iterable): # real signature unknown; restored from __doc__
        pass

    def __iter__(self, *args, **kwargs): # real signature unknown
        """ Implement iter(self). """
        pass

    @staticmethod # known case of __new__
    def __new__(*args, **kwargs): # real signature unknown
        """ Create and return a new object.  See help(type) for accurate signature. """
        pass

    def __next__(self, *args, **kwargs): # real signature unknown
        """ Implement next(self). """
        pass

    def __reduce__(self, *args, **kwargs): # real signature unknown
        """ Return state information for pickling. """
        pass

看源碼發現竟然是個類。測試

它接收到的是2個參數,2個參數在哪裏看呢?優化

__init__方法裏面看。既然是個類,調用的時候建立一個對象。rest

Python 中的可迭代對象在一個模塊裏面。迭代器、生成器、可迭代對象都在這個模塊裏面。code

from collections import Iterator,Iterable,Generatororm

生成器屬於迭代器,生成器是可迭代對象。

列表是個可迭代對象。filter()這個內置函數傳 2 個參數後,會返回出一個對象。

filter()源碼能夠看出它是個類,調用它給它傳參,類返回的結果確定是個對象。

filter()的做用是過濾,它會進行迭代操做。

它會把後面傳入的可迭代對象,裏面的元素所有遍歷一遍。而後把遍歷出來的元素看成參數傳到這個fun函數裏面。

當前這個fun()函數沒有定義參數,這個時候運行看看:

# 內置函數
def fun():
    pass

li = [1,2,122,331,11,22,33,4,6,7,2,88,31]

res=filter(fun,li)
print(list(res))

返回列表的時候報錯了,fun()須要 0 個參數,可是這裏給了一個參數:

當咱們把它轉換成列表的時候,在這裏傳進去,它會返回一個對象,這個對象裏有一個函數,還有個可迭代對象filter(fun,li)

使用filter()傳出來的數據也是個迭代器。它也是個可迭代對象,就能夠經過list把它轉換成列表。

當你轉換的時候,它會把第一個參數拿到,傳到fun()裏面去,會自動傳參的。

加個參數,再運行:

# 內置函數
def fun(n):
    pass

li = [1,2,122,331,11,22,33,4,6,7,2,88,31]

res=filter(fun,li)
print(list(res))

運行結果:

這個列表是空的。由於函數pass掉了。只寫個pass,調用這個函數,返回的值是沒有結果的。

filter()會根據傳進去的參數,調用func()函數,這個函數根據返回值pass,來肯定函數li要不要添加到新的列表裏面。

若是將代碼修改爲這樣return True

def fun(n):
    return True

li = [1,2,122,331,11,22,33,4,6,7,2,88,31]

res=filter(fun,li)
print(list(res))

返回結果:

返回一個 False:

輸出結果是一個都沒有了。

filter()函數能夠過濾,能夠寫過濾條件。好比要保留n<10的數據要保留下來,n<10是個比較語句。

n<10返回的是個 True(當前傳入的參數保留,添加到新的列表裏面),n>10返回的是個 False(就把數據去掉不要了):

def fun(n):
    return n<10

li = [1,2,122,331,11,22,33,4,6,7,2,88,31]

res=filter(fun,li)
print(list(res))

其實和這段代碼的操做是同樣同樣的:

li1 = []
for i in li:
    if i > 10:
        li1.append(i)

內部操做是這樣的:

定義了個新的列表li1,在這裏面來了一個for循環,判斷i是否是大於 10,若是大於 10,就把它添加到新的列表裏面。

會根據你傳入的參數fun(n)進行相應的判斷和比較。根據函數返回的是True仍是None,來決定這個數據要不要保留起來。

2.生成器、迭代器都是可迭代對象

定義個生成器、可迭代對象、迭代器:

from collections import Iterator,Iterable,Generator
def fun(n):
    return n < 10

# 列表就是可迭代對象
li = [1, 2, 122, 331, 11, 22, 33, 4, 6, 7, 2, 88, 31]
res = filter(fun, li)

# 定義個迭代器
# 能夠把一個可迭代對象轉換成一個迭代器
li2 = iter(li)

# 定義個生成器
li3 = (i for i in range(5))

# 用isinstance 判斷下列表是否是個可迭代對象
print(isinstance(li,Iterable))
print(isinstance(li2,Iterable))
print(isinstance(li3,Iterable))

isinstance() 函數來判斷一個對象是不是一個已知的類型,相似 type()

返回都是True,因此它們 3 個都是可迭代對象。

生成器屬於迭代器,那麼生成器也是可迭代對象。迭代器是可迭代對象,可是迭代器不是生成器。

2、map()函數

map()的機制和filter()是同樣的。它也會將後面的可迭代對象裏面的數據迭代出來,放到第一個函數裏面。

它接收的也是 2 個參數。第一個參數:func ,第二個參數:可迭代對象。

def fun(n):
    return n < 10

# 列表就是可迭代對象
li = [1, 2, 122, 331, 11, 22, 33, 4, 6, 7, 2, 88, 31]
res = filter(fun, li)

# map:將可迭代對象中的數據迭代出來,一個一個傳到函數中去調用,將返回結果放到新的對象中。
res2=map(fun,li)
print(list(res2))

它返回的結果全是TrueFalse

map()函數能夠用來作:

1.把這些數據作統一的處理,好比算這些數據的階乘,有一批數據要算階乘,能夠一塊兒拿過去。

2.它會把數據看成個參數,放到函數裏去調用。

3.而後把函數的返回值放到一個列表裏面。

它返回什麼就放什麼,改爲返回 1000:

改爲n*2:

map()將可迭代對象裏面的元素迭代出來,每一個元素看成一個參數,傳到前面這個函數fun裏面,而後把函數的返回值添加到新的列表裏面。

要統一處理一批數據的時候,就能夠經過它來作。

3、zip()函數

1.什麼是 zip()函數

zip()函數後面接收的是個可迭代對象,後面可接收多個可迭代對象。

來看看 zip 的源碼:

它的內部其實也是個類,那麼它返回的就是個可迭代對象。

準確得來講,它是個迭代器,迭代器也屬於可迭代對象。

例如:

# zip # 打包
res3 = zip([1, 2, 3], [11, 22, 33])
print(res3)

在 Python2 的時候,filter()map()zip()函數返回出來的直接是列表。Python3 作了個性能的優化,返回的是個迭代器,能夠節約內存。

經過next()去取值,能獲取出來內容的話,說明它就是個迭代器:

直接一次性把它轉換成列表,方便看結果:

# zip # 打包
res3 = zip([1, 2, 3], [11, 22, 33])
print(list(res3))

它是這樣打包的:

使用zip()函數傳入 2 個可迭代對象,把第一個可迭代對象的第一個元素和第二個可迭代對象的第一個元素拿出來打包成一個元組,後面以此類推。

爲何裏面放的是元組?

元組省內存啊。

若是可迭代對象裏面元素多少不同(長短不一)怎麼辦?

# zip # 打包
res3 = zip([1, 2, 3], [11, 22, 33,44,55],[111,222,333],[111,222,333])
print(list(res3))

它會只會保留最短的。

代碼中最短的一組:這裏只有 3 個元素。

那麼這裏的話,只會分紅 3 組。就算第二組有 5 個元素,只會拿第一個、第二個、第三個。多餘的數據清除掉了,不要了。

2.zip()能夠快速建立字典

你看,和字典items()取值出來的數據是同樣的:

經過dict轉換下,你看,它變成了一個字典:

# zip # 打包
res3 = zip([1, 2, 3], [11, 22, 33])
print(dict(list(res3)))

dict1={"key1":1,"key2":2,"key3":3}
print(list(dict1.items()))

建立字典的時候,可經過這種方式快速建立字典。

把鍵放在一個列表裏,把值放在一個列表裏,經過zip()打包一下,經過dit()就能把它轉換成一個字典。


公衆號清菡軟件測試首發,更多原創文章:清菡軟件測試 112+原創文章,歡迎關注、交流,禁止第三方擅自轉載。

相關文章
相關標籤/搜索