函數式程式設計
上學期有上一門叫'人工智慧' 的課,老師強行要我們學了一個叫做prolog 的語言,哇那感覺確實難受,思維方式完全和之前學過的不一樣,寫個漢諾塔想了半天,最後還是在網上找了段代碼修改一下(怕被老師發現抄襲)才寫出來,貼一段出來感受一下:
hanoi(N) :- dohanoi(N, 'a', 'b', 'c'). dohanoi(0, _ , _ , _ ) :- !. dohanoi(N, A, B, C) :- N1 is N-1, dohanoi(N1, A, C, B), writeln([move, N, A-->C]), dohanoi(N1, B, A, C).
當時是差不多弄懂了,主要是資料實在太少,debug 都無從談起,一遇上bug 就gg,我現在自己看也有點頭暈。不過據說 prolog 當年能和 Lisp 一爭高下,最近對 Lisp 也有點興趣,等弄完這些就去參拜一下這類函數式語言。
何謂函數式程式設計?廖大這裡寫道:
函數式程式設計就是一種抽象程度很高的程式設計範式,純粹的函數式程式語言所寫的函數沒有變量,因此,任意一個函數,只要輸入是確定的,輸出就是確定的,這種純函數我們稱之為沒有副作用。而允許使用變數的程式設計語言,由於函數內部的變數狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函數是有副作用的。
可能看完還是有些不太理解,不急,先看完這幾個小節吧。
高階函數
在數學和電腦科學中,高階函數是至少滿足下列一個條件的函數:
接受一個或多個函數作為輸入
-
輸出一個函數
是說,把函數本身當成參數傳遞,或是回傳一個函數。
>>> min(1, 2) 1 >>> f = min >>> f(1, 2) 1 >>> f <built-in> >>> min <built-in></built-in></built-in>也可以給函數賦值(代碼接上):
>>> min = 10 >>> min(1, 2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object is not callable >>> f(1, 2) 1 >>> min = f >>> min(1, 2) 1</module></stdin>還可以傳參,例如,一個計算所有數字的和的函數:
>>> def add(a, b): ... return a+b ... >>> def mysum(f, *l): ... a = 0 ... for i in l: ... a = f(a, i) ... return a ... >>> mysum(add, 1, 2, 3) 6 >>> mysum(add, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) 55當然,將這個f 換成乘法就是計算所有數字的乘積了。 再來看看 python 內建的一些高階函數,常常會用到。 map/reduce記得上學期上雲端運算的課程時依稀有聽過這個詞,不過這課很水,就沒怎麼聽,在這裡看到好像發現不太一樣? ? 不過沒啥說的,簡單說一下每個函數的作用。 對於 map,其計算式可以看成這樣:
map(f, [x1, x2, ..., xn]) = [f(x1), f(x2), ..., f(xn)]對於 reduce,其計算式可以看成這樣:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)廖大那裡說得很清楚啦。 filterfilter 和 map 函數類似,接受一個函數和 iterable,傳回也是一個 list,不過其功能是根據函數傳回值是否為 True 來判斷是否保留該值。例如:
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# 结果: [1, 5, 9, 15]
sortedsorted 函數同樣是一個高階函數,對參數key 傳遞函數可以將需要排列的序列經過key 函數處理後再進行排序,不過不會改變序列的值,例如:>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
裝飾器(decorator)匿名函數就不說了,以後用時再仔細看吧,裝飾器我記得之前看flask 的時候都研究了好久,這次再來複習一下。 簡單裝飾器首先是一個簡單的裝飾器,在每次調用函數前打印出日誌:import logging
def log(func):
def wrapper(*args, **kw):
logging.warn("%s is running" % func.__name__)
func(*args, **kw)
return wrapper
這就是一個極其簡單的裝飾器,如何使用它呢?我最先看到的用法是在需要裝飾的函數前面加上@,但其實這是Python 的一個語法糖,最原始的用法反而更能讓人理解,先定義一個函數f:
def f(): print("in function f") f = log(f)這樣定義了之後,我們再呼叫f 函數:
>>> f() WARNING:root:f is running in function f使用@log 的結果與其一樣,其實@符號作為裝飾器的語法糖,與前面的賦值語句具有相同的功能,使代碼看起來更簡潔明了,避免再一次賦值操作,就像下面這樣:
@log def f(): print("in function f")含參數的裝飾器有時候我們還需要向裝飾器中傳入參數,例如,狀態,層次等信息,只需要在wrapper 函數外再'包裹'一層函數,如下所示:
import logging
def log(level):
def decorator(func):
def wrapper(*args, **kw):
logging.warn("%s is running at level %d" % (func.__name__, level))
return func(*args, **kw)
return wrapper
return decorator
@log(2)
def f():
print("in function f")
>>> f()
WARNING:root:f is running at level 2
in function f
進一步理解為了再進一步理解裝飾器,我們可以打印出函數f 的name 屬性:#对于不加装饰器的 f,其 name 不变
>>> def f():
... print("in function f")
...
>>> f.__name__
'f'
#对于添加装饰器的函数,其 name 改变了
>>> @log
... def f():
... print("in function f")
...
>>> f.__name__
'wrapper'
聯繫到最前面的裝飾器賦值語句,就可以大致明白髮生了什麼:f = log(f)
使得f 指向修改為log(f) 的回傳值,即wrapper 函數。每次執行原函數 f 時,則會呼叫 wrapper 函數,在我們這個範例中,則是先列印日誌,然後執行原函數 f。不過這樣有一個問題,這樣使得原函數f 的元資訊被替換了,關於f 的許多資訊消失不見,這是很難令人接受的,不過好在我們有functools 模組,修改函數為:
import functools import logging def log(func): functools.wraps(func) def wrapper(*args, **kw): logging.warn("%s is running" % func.__name__) func(*args, **kw) return wrapper >>> @log ... def f(): ... print("in function f") ... >>> f.__name__ 'f'另外,還可以對同一個函數添加多個裝飾器:
@a @b @c def f (): # 等价于 f = a(b(c(f)))總結關於函數式編程我也不是很了解,這裡只是大概了解了一下其概念吧,平時肯定還是使用命令式編程用得多。不過有語言是純函數式語言,例如 Haskell 或 Lisp,學習它們會讓人打開一種新思路。 更多[python] 初探'函數式程式設計'相關文章請關注PHP中文網!

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于Seaborn的相关问题,包括了数据可视化处理的散点图、折线图、条形图等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于进程池与进程锁的相关问题,包括进程池的创建模块,进程池函数等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于简历筛选的相关问题,包括了定义 ReadDoc 类用以读取 word 文件以及定义 search_word 函数用以筛选的相关内容,下面一起来看一下,希望对大家有帮助。

VS Code的确是一款非常热门、有强大用户基础的一款开发工具。本文给大家介绍一下10款高效、好用的插件,能够让原本单薄的VS Code如虎添翼,开发效率顿时提升到一个新的阶段。

pythn的中文意思是巨蟒、蟒蛇。1989年圣诞节期间,Guido van Rossum在家闲的没事干,为了跟朋友庆祝圣诞节,决定发明一种全新的脚本语言。他很喜欢一个肥皂剧叫Monty Python,所以便把这门语言叫做python。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于数据类型之字符串、数字的相关问题,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于Python的相关知识,其中主要介绍了关于numpy模块的相关问题,Numpy是Numerical Python extensions的缩写,字面意思是Python数值计算扩展,下面一起来看一下,希望对大家有帮助。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載
最受歡迎的的開源編輯器

Dreamweaver Mac版
視覺化網頁開發工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。