reduce,map,filter,lambda等python內置函數解析

如何寫出優雅的python腳本程序。作爲一款最接近機器學習,深度學習的腳本語言,python有着其獨特的編程風格,高效的編程方式。請看下面的代碼。

    1、輸入一個列表,將列表中的所有非數字的字符去掉,並且將數字字符進行排序。

class Solution:
    def __init__(self):
        pass

    @staticmethod
    def get_data():
        str_data = str(input()).strip()
        return str_data

    @staticmethod
    def sort_dig_data(str_data):
        dig_data = [int(cur_data) for cur_data in str_data if cur_data.isdigit()]
        dig_data.sort(key=None, reverse=False)
        return dig_data
if __name__ == '__main__':
    print(Solution.sort_dig_data(Solution.get_data()))
vdfnbij45769568jhotyj
[4, 5, 5, 6, 6, 7, 8, 9]

    也許,這樣就達到了排序的目的。首先去掉了非數字字符,並且將數字字符轉化成數字,然後按照升序排列。但是,我們能否有更好的方式,寫出更優雅的表達式?

    將sort_dig_data函數修改爲:_sort_did_data,代碼如下:

@staticmethod
def _sort_dig_data(str_data):
    dig_data = list(map(int, filter(lambda cur_data: cur_data.isdigit(), str_data)))
    dig_data.sort(key=None, reverse=False)
    return list(dig_data)
vdfnbij45769568jhotyj
[4, 5, 5, 6, 6, 7, 8, 9]

    1.1函數解析。

        filter函數。filter,顧名思義,就是過濾,啥爲過濾,想必大家應該都很清楚。要達到過濾的效果至少組要兩個方面的內容: 過濾規則,待過濾的內容(可以是字符串,列表,元組等數據組織形式),不能再比這還少了吧。我們舉個例子:
還是過濾掉一個字符串中的非數字字符,代碼如下:
def filter_no_dig(data):
    dig_data = filter(lambda cur_str_char: cur_str_char.isdigit(), data)
    return list(dig_data)

if __name__ == '__main__':
    print(filter_no_dig('fwijbnb9527bonb4945uy'))
結果:['9', '5', '2', '7', '4', '9', '4', '5']

        也許有像我這樣的初學者會問:匿名函數 lambda 後面的cur_str_char參數的值是怎麼被賦值的? 當然後面會講到lambda。其實data是個字符串,是一個可以被迭代的對象,也就是可以被循環取值。所有每次順序的從data裏面拿到一個數,單後將這個數賦值給cur_str_char參數,然後根據判斷條件isdigit()的真假來決定是否將不符合條件的值給去掉,上面的那個程序與下面的程序是等價的。

def _filter_no_dig(data):
    # dig_data = filter(lambda cur_str_char: cur_str_char.isdigit(), data)
    dig_data = [int(cur_data) for cur_data in data if cur_data.isdigit()]
    return list(dig_data)

           當然上面的那個filter函數的過濾規則我使用的是匿名函數lambda。其實filter_no_dig函數與下面的函數也是等價的

def filter_rule(chr_char):
    if chr_char.isdigit():
        return True
    else:
        return False


def filter_no_dig(data):
    dig_data = filter(filter_rule, data)
    return list(dig_data)

        map函數。map函數就是一個映射函數,映“射”大家都知道吧,不過這裏是一一映“”。就是對待映射的對象(包括列表等)按照某個規則進行映“”。所以按照我們的理解,要完成這個任務,我們的map函數至少需要如下基本信息:映“”規則,待射對象。這裏還是給出一個函數。

def map_data(data):
    return list(map(lambda cur_data: int(cur_data)**2, data))

if __name__ == '__main__':
    print(map_data('95274945'))
運行結果:[81, 25, 4, 49, 16, 81, 16, 25]

        這裏的映“”規則我還是使用匿名函數,當然這個函數與下面的函數是等價的。

def map_relu(cur_data):
    if isinstance(cur_data, int):
        return cur_data**2
    elif cur_data.isdigit():
        return int(cur_data)**2
    else:
        assert 'data type error......'


def map_data(data):
    return list(map(map_relu, data))

if __name__ == '__main__':
    print(map_data('95274945'))

       大家有沒有發現幾個等價的函數全部都是把使用lambda定義的匿名函數使用傳統的def函數定義方式進行顯式的表示?希望大家能夠認真的體味。 

        lambda函數。前面已經使用過lambda函數,這裏我就不再寫函數驗證了。首先,lambda是一個表達式,而不是一個函數。至於lambda的定義網上有很多,這裏我不再贅述,因爲這篇博客,我打的是原創的標籤,拷貝別淫的陳述似乎不大好。

        lambda函數接收多個參數,並且會使用這些參數值進行若干運算,並且返回運算結果。

        下面還是實現一個很經典的排序問題。對一個字典,按照value值對其進行排序。

        一、不使用lambda函數。

def sort_dict():
    data = dict()
    list_data = [(9, 'line'), (5, 'five'), (2, 'two'), (7, 'seven')]
    for cur_data in list_data:
        data.update({cur_data[0]: cur_data[1]})
    return sorted(list(zip(data.values(), data.keys())))

if __name__ == '__main__':
    print(sort_dict())

思路很簡單,就是先將dict的值和key都拿出來組建成一個元組然後將元組作爲列表的基本單元,構建一個列表。然後對列表進行排序,由於列表中的每個元素都是一個元組,即二元組,所以sorted排序的時候默認使用第一個值進行排序。所以會有上面的效果。

        二、使用lambda函數。

def sort_dict():
    data = dict()
    list_data = [(9, 'line'), (5, 'five'), (2, 'two'), (7, 'seven')]
    for cur_data in list_data:
        data.update({cur_data[0]: cur_data[1]})
    # return sorted(list(zip(data.values(), data.keys())))
    return sorted(data.items(), key=lambda lambda_data: lambda_data[1])

if __name__ == '__main__':
    print(sort_dict())

    2 reduce函數解析。

    reduce函數實現的功能很簡單,實現的是列表的累積求和。還是給出一個函數:
from functools import reduce

def reduce_fu():
    data = [9, 5, 2, 7]
    return reduce(lambda cur_data, cur_data1: cur_data+cur_data1, data)

if __name__ == '__main__':
    print(reduce_fu())
23

        這個函數等價於:

from functools import reduce


def sum_relu(cur_data, cur_data1):
    assert isinstance(cur_data, int) and isinstance(cur_data1, int), 'data type error......'
    return sum([cur_data, cur_data1])

def reduce_fu():
    data = [9, 5, 2, 7]
    return reduce(sum_relu, data)

if __name__ == '__main__':
    print(reduce_fu())
        以上的所有函數都是自己寫的,希望大家能夠認真體味。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章