小白的Python 學習筆記(五)map, filter, reduce, zip 總結

簡潔的內置函數

你們好,我又回來了,今天我想和你們分享的是Python很是重要的幾個內置函數:map,filter,reduce, zip。主要用處在於處理序列(Sequence)。咱們能夠利用它們把一些小函數應用於一個序列的全部元素。從而節省編寫顯式循環的時間。python

另外,map,filter,reduce, zip都是純函數,有返回值。所以咱們能夠容易地將函數的返回結果用表達式來表示。數組

我我的的理解是使用它們,能夠簡化咱們的代碼,從而更簡潔高效地執行一些須要用到循環迭代的任務,接下來是一些具體例子bash

map()

函數構造app

map()函數的主要做用是能夠把一個方法依次執行在一個可迭代的序列上,好比List等,具體的信息以下:函數

  • 基礎語法:map(fun, iterable)
  • 參數:fun是map傳遞給定可迭代序列的每一個元素的函數。iterable是一個能夠迭代的序列,序列中的每個元素均可以執行fun
  • 返回值:map object

其實就是利用map映射,咱們能夠把一個函數fun 執行到序列iterable的每個元素上,用例子很是好理解~學習

基礎用法:測試

下面先讓咱們看一個小例子,假設如今咱們有一個List,包含1~5五個數字,咱們想要讓每個數+1,若是不知道map這個函數以前,咱們的解決方案是這樣的:優化

numbers = [1, 2, 3, 4, 5]
for i in range(0,len(numbers)):      #對每一個元素加1
    numbers[i]+=1 
print(numbers)

Out:[2, 3, 4, 5, 6]
複製代碼

或者是這樣的:ui

numbers = [1, 2, 3, 4, 5]
result = []
for n in numbers:
    result.append(n+1)
print(result)
Out:[2, 3, 4, 5, 6]
複製代碼

這裏用列表表達式會更好,我會在以後的文章總結spa

可是顯然,不管怎麼作都會涉及到寫循環,這裏就是map函數的用武之地了,咱們能夠用map函數這樣實現:

def add_one(n):
    return n + 1

numbers = [1, 2, 3, 4, 5]
result = map(add_one, numbers)
print(result)
print(type(result))
print(list(result))

Out:<map object at 0x00000260F508BE80>
    <class 'map'>
    [2, 3, 4, 5, 6]
複製代碼

這裏咱們發現了map的好處,在精簡代碼的同時,某種程度上實現了方法和循環部分的分離,這裏咱們發現map返回就是map類,咱們這裏傳遞的序列是List,最後輸出時通過類型轉換也是list

在傳遞序列時只要這個序列是可迭代的就好,不必定非要List,好比咱們換一種:

def add_one(n):
    return n + 1
    
numbers = (1, 2, 3, 4, 5)     #序列爲元組
result = map(add_one, numbers)
print(tuple(result))          #

Out:(2, 3, 4, 5, 6)
複製代碼

輸入的序列爲一樣能夠迭代的元組,輸出時咱們也選擇元組,效果同樣的。

如今優化一下,還用剛纔的例子,爲了更簡潔,咱們用lambda函數配合map使用:

numbers = (1, 2, 3, 4, 5)                     # 迭代對象爲tuple
result = map(lambda x: x + 1, numbers)
print(list(result))                           # 輸出對象爲list
 
Out:[2, 3, 4, 5, 6]

複製代碼

更加簡潔優雅了對吧!!這個lambda函數我以後會說,今天它不是主角,先一帶而過。讓咱們從新把目光轉移到map上來,除了剛纔的用法,還要一種狀況也十分常見,像以下這個例子:

# List of strings
words = ['paris', 'xiaobai','love']

# 把數組中每一個元素變爲List
test = list(map(list, words))
print(test)

Out: [['p', 'a', 'r', 'i', 's'], ['x', 'i', 'a', 'o', 'b', 'a', 'i'], ['l', 'o', 'v', 'e']]
複製代碼

words是一個只包含字符串類型元素的list,咱們用map能夠實現將words的每個元素所有轉化爲list類型,這裏有一點必定要注意,能實現的前提必定是每一個元素都是能夠迭代的類型,若是出現瞭如int類型的元素,就會出錯啦:

# List of strings
words = [18,'paris', 'xiaobai','love']

# 把數組中每一個元素變爲List
test = list(map(list, words))
print(test)

Out:TypeError: 'int' object is not iterable

複製代碼

你們一看錯誤類型相比馬上就明白了,因此正確的使用方法必定是相似這種:

nums = [3,"23",-2]
print(list(map(float,nums)))

Out: [3.0, 23.0, -2.0]

複製代碼

總之就是類型要注意,我僅僅是拋磚引玉簡單介紹一下map,具體的用法你們能夠自行開發哈,我也在不斷學習中

filter()

函數構造

filter()方法藉助於一個函數來過濾給定的序列,該函數測試序列中的每一個元素是否爲真。

  • 基礎語法:filter(fun, iterable)
  • 參數:fun測試iterable序列中的每一個元素執行結果是否爲True,iterable爲被過濾的可迭代序列
  • 返回值:可迭代的序列,包含元素對於fun的執行結果都爲True

簡而言之就是filter能夠幫助咱們根據給出的條件過濾一組數據並返回結果

基礎用法:

讓咱們先看一個例子:

# 過濾元音的方法
def fun(variable):
    letters = ['a', 'e', 'i', 'o', 'u']
    if (variable in letters):
        return True
    else:
        return False

# 給定序列
sequence = ['I', 'l', 'o', 'v', 'e', 'p', 'y','t','h','o','n']

# 根據條件得出結果
filtered = list(filter(fun, sequence))
print(filtered)

Out:['o', 'e', 'o']
複製代碼

這裏咱們建立一個能夠提取元音字母的方法fun,給定的可迭代序列爲list,以後就能夠用filter方法很容易的提取出結果啦,再看一個相似例子:

# 判斷爲正數
def positive(num):
    if num>0:
        return True
    else:
        return False

#判斷偶數
def even(num):
    if num % 2==0:
        return True
    else:
        return False

numbers=[1,-3,5,-20,0,9,12]

positive_nums = list(filter(positive, numbers))
print(positive_nums)  # 輸出正數 list


even_nums = tuple(filter(even,numbers))
print(even_nums)     #輸出偶數 tuple

Out:[1, 5, 9, 12]
     (-20, 0, 12)
複製代碼

看到這裏相比你們已經知道filter的基礎用法, 要先有一個能返回True或者False的方法,或者表達式做爲過濾條件就好了

更進一步

這裏其實和map同樣了,基本上最簡潔的用法都是和lambda混在一塊兒,好比下面咱們想要把剛纔的一大串代碼壓縮一下:

numbers = [0, 1, 2, -3, 5, -8, 13]

# 提取奇數
result = filter(lambda x: x % 2, numbers)
print("Odd Numbers are :",list(result))

# 提取偶數
result = filter(lambda x: x % 2 == 0, numbers)
print("Even Numbers are :",list(result))

#提取正數
result = filter(lambda x: x>0, numbers)
print("Positive Numbers are :",list(result))

Out:Odd Numbers are : [1, -3, 5, 13]
     Even Numbers are : [0, 2, -8]
     Positive Numbers are : [1, 2, 5, 13]

複製代碼

" 爽啊!爽死了!" 郭德綱看到後這麼評價,lambda我平時用的很少,可是這裏使用正好能夠體現python的理念之一:高效簡潔!

reduce()

函數構造

Reduce是一個很是有用的函數,用於在列表上執行某些計算並返回結果。它將滾動計算應用於列表中的連續值。例如,若是要計算整數列表的累積乘,或者求和等等

  • 基礎語法:reduce(function, iterable)
  • 參數:fun是連續做用於iterable每個元素的方法,新的參數爲上一次執行的結果,iterable爲被過濾的可迭代序列
  • 返回值:最終的function返回結果

在Python 2中,reduce()是一個內置函數。可是,在Python 3中,它被移動到functools模塊。所以,要使用前咱們須要導入,這裏個人環境是Python 3.6

基礎用法:

先看一個求累加和的小栗子:

from functools import reduce # Python 3

def do_sum(x1, x2): 
    return x1 + x2
    
print(reduce(do_sum, [1, 2, 3, 4]))

Out:10
複製代碼

再看一個累積乘法的例子:

from functools import reduce # Python 3
def multiply(x, y):
    return x*y

numbers = [1,2,3,4]
print(reduce(multiply, numbers))

Out:24
複製代碼

更進一步:

仍是和lambda混搭,更加簡潔:

from functools import reduce # Python 3
numbers = [1,2,3,4]
result_multiply = reduce((lambda x, y: x * y), numbers)
result_add = reduce((lambda x,y: x+y), numbers)

print(result_multiply)
print(result_add)

Out:24
     10
複製代碼

zip()

函數構造

zip()的目的是映射多個容器的類似索引,以便它們能夠僅做爲單個實體使用。

  • 基礎語法:zip(*iterators)
  • 參數:iterators爲可迭代的對象,例如list,string
  • 返回值:返回單個迭代器對象,具備來自全部容器的映射值

基礎用法:

其實以前咱們在講dict的建立方法時提到過它,這裏重新回顧一下:

keys = ['name','age']
values = ['xiaobai',18]
my_dict = dict(zip(keys,values))
print(my_dict)

Out:{'name': 'xiaobai', 'age': 18}

複製代碼

zip能夠支持多個對象,好比下面的例子

name = [ "xiaobai", "john", "mike", "alpha" ]
age = [ 4, 1, 3, 2 ]
marks = [ 40, 50, 60, 70 ]

# using zip() to map values
mapped = list(zip(name, age, marks))
print ("The zipped result is : "mapped)

Out:The zipped result is : [('xiaobai', 4, 40), ('john', 1, 50), ('mike', 3, 60), ('alpha', 2, 70)]

複製代碼

這裏咱們能夠很容易的的把name,age,marks這三個list裏面相同index的值映射打包在一塊兒

更進一步:

經過上面的例子,咱們發現能夠很容易的以相似1對1的形式把不一樣對象的同一索引位置的值打包起來,那若是是解包呢?也是相似的,就是多了一個 * 而已

names, ages, marks = zip(*mapped)
print ("The name list is : ",names)
print ("The age list is : ",ages)
print ("The marks list is : ",marks)

Out: The name list is :  ('xiaobai', 'john', 'mike', 'alpha')
     The age list is :  (4, 1, 3, 2)
     The marks list is :  (40, 50, 60, 70)
複製代碼

總結

今天主要爲你們介紹了map,filter,reduce,zip四個高效的python內置函數的用法,我也是剛剛接觸,瞭解不夠深刻,若是介紹的有錯誤或者歧義還請你們多多諒解和包容,若是有大神能夠進一步補充說明必定要寫個評論呀,讓咱們一塊兒進步。

相關文章
相關標籤/搜索