一等函數

在python中,支持面向對象,也支持面向過程編程。字典,整數等這些都是對象,那麼函數呢?答案:函數也是對象,在python中,一切都是對象。python

1、函數也是對象

實例編程

def funca():  # 建立一個函數
    """返回ok"""
    return 'ok'

print(funca.__doc__) 
print(funca)
print(funca()) 
type(funca)

輸出app

返回ok  #  __doc__ 是函數對象衆多屬性中的一個
<function funca at 0x00000257BDAC2598>  # 函數對象在內存中的地址
ok  # 函數的返回值
function  # funca 是 function 類的實例

爲了更進一步說明函數式對象,能夠把函數賦值給其餘變量,或者把函數對象做爲參數傳遞給其餘函數。ssh

>>> fact = factorial
>>> fact
<function factorial at 0x...>
>>> fact(5)
120
>>> map(factorial, range(11))
<map object at 0x...>
>>> list(map(fact, range(11)))
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

2、高階函數

什麼是高階函數:接受函數爲參數,或者把函數做爲結果返回的函數是高階函數
常見高階函數函數

- map
- filter
- reduce
- apply
- sorted

一、 sorted

內置函數 sorted :可選的 key 參數用於提供一個函數,它會應用到各個元素上進行排序ui

實例1、

根據單詞長度給一個列表排序,據單詞的長度排序,只需把 len 函數傳給 key 參數code

>>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
>>> sorted(fruits, key=len)
['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']
>>

實例2、

根據反向拼寫給一個單詞列表排序,下面例子中列表裏的單詞沒有變,咱們只是把反向拼寫看成排序條件orm

>>> def reverse(word):
... return word[::-1]
>>> reverse('testing')
'gnitset'
>>> sorted(fruits, key=reverse)
['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
>>>

二、map

map()函數接收兩個參數,一個是函數,一個是序列,map將傳入的函數依次做用到序列的每一個元素,並把結果做爲新的list返回。對象

實例1、

有一個函數f(x)=x2,要把這個函數做用在一個list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就能夠用map()實現以下排序

>>> def f(x):
...     return x * x
...
>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])  # map()傳入的第一個參數是f,即函數對象自己。
[1, 4, 9, 16, 25, 36, 49, 64, 81]

實例2、

把這個list全部數字轉爲字符串

>>> map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])
['1', '2', '3', '4', '5', '6', '7', '8', '9']

三、 reduce

reduce() 函數會對參數序列中元素進行累積。
函數將一個數據集合(鏈表,元組等)中的全部數據進行下列操做:用傳給 reduce 中的函數 function(有兩個參數)先對集合中的第 一、2 個元素進行操做,獲得的結果再與第三個數據用 function 函數運算,最後獲得一個結果。

實例1、

>>> from functools import reduce  # 在python3,reduce不在做爲內置函數出現
>>> from operator import add 
>>> reduce(add, range(100)) 
4950
>>> sum(range(100)) 
4950
>>>

>>> def fn(x, y):
...     return x * 10 + y
...
>>> reduce(fn, [1, 3, 5, 7, 9])  # 將序列直接轉化成整數
13579

實例2、

將一個str對象轉化內int對象

>>> def fn(x, y):
...     return x * 10 + y
...
>>> def char2num(s):
...     return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
...
>>> reduce(fn, map(char2num, '13579'))
13579

參考自廖雪峯教程

四、filter

filter() 函數用於過濾序列,過濾掉不符合條件的元素,返回一個迭代器對象,若是要轉換爲列表,可使用 list() 來轉換。
該接收兩個參數,第一個爲函數,第二個爲序列,序列的每一個元素做爲參數傳遞給函數進行判,而後返回 True 或 False,最後將返回 True 的元素放到新列表中。

實例

在一個list中,刪掉偶數,只保留奇數,能夠這麼寫:

def is_odd(n):
    return n % 2 == 1

filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])
# 結果: [1, 5, 9, 15]

五、map和filter的替代品

在 Python 3 中,map 和 filter 仍是內置函數,可是因爲引入了列表推導和生成器表達式,它們變得沒那麼重要了。列表推導或生成器表達式具備 map 和 filter 兩個函數的功能,並且更易於閱讀,
計算階乘列表:map 和 filter 與列表推導比較

>>> list(map(fact, range(6))) 
[1, 1, 2, 6, 24, 120]
>>> [fact(n) for n in range(6)] 
[1, 1, 2, 6, 24, 120]
>>> list(map(factorial, filter(lambda n: n % 2, range(6)))) 
[1, 6, 120]
>>> [factorial(n) for n in range(6) if n % 2] 
[1, 6, 120]
>>>

六、 any和all

  • all(iterable):若是 iterable 的每一個元素都是真值,返回 True;all([]) 返回True。
  • any(iterable):只要 iterable 中有元素是真值,就返回 True;any([]) 返回False。

3、匿名函數

lambda 關鍵字在 Python 表達式內建立匿名函數。匿名函數是爲了解決函數對象的命名繁瑣而存在的,可是使用匿名函數又大大下降了代碼的可閱讀性,因此除了在高階函數將匿名函數做爲參數之外,不多使用匿名函數。
在參數列表中最適合使用匿名函數。
以下:使用 lambda 表達式反轉拼寫,而後依此給單詞列表排序

>>> fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']
>>> sorted(fruits, key=lambda word: word[::-1])
['banana', 'apple', 'fig', 'raspberry', 'strawberry', 'cherry']
>>>

4、可調用的對象

用戶自定義的函數對象一般是可調用的,能夠經過()運算符應用到可調用的對象,例如內置函數str

>>>mystr = 123
>>>str(mystr) # mystr內置函數是可調用的
'123'

那麼除了它,Python中的其餘對象是否可調用呢,可使用內置的 callable() 函數。

>>> abs, str, 13
(<built-in function abs>, <class 'str'>, 13)
>>> [callable(obj) for obj in (abs, str, 13)]
[True, True, False]

Python 數據模型文檔列出了 7 種可調用對象。

  • 用戶定義的函數:使用 def 語句或 lambda 表達式建立。
  • 內置函數:使用 C 語言(CPython)實現的函數,如 len 或 time.strftime。
  • 內置方法:使用 C 語言實現的方法,如 dict.get。
  • 方法:在類的定義體中定義的函數。
  • 類 
  • 類的實例
  • 生成器函數 :使用 yield 關鍵字的函數或方法。調用生成器函數返回的是生成器對象

5、函數內省

既然把函數做爲對象看待,那麼就應該具備對象同樣的特性:內省
內省是什麼:內省指一種能力,能夠肯定對象是什麼,包含何種信息,能夠作什麼。
像這樣使用 dir 函數能夠探知factorial 具備下述屬性:

>>> dir(factorial)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__',
'__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__',
'__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__']
相關文章
相關標籤/搜索