python-函數式編程-22

## python語言的高級特性python

#函數式編程(Functional Programming)
-基於lambda演算的一種編程方式
  -程序中只有函數
  -函數能夠做爲參數,一樣能夠做爲返回值
  -純函數式編程語言:LISP Haskell
-python函數式編程知識借鑑函數式編程的一些特色,能夠理解爲是一半函數一半python
-概念
  -高階函數
  -返回函數
  -匿名函數
  -裝飾器
  -偏函數
算法

#lambda表達式
-函數:最大程度複用代碼
  -存在的問題:若是函數很小,很短,採用函數式編程則會比較囉嗦
  -若是函數被調用次數少,則會浪費
  -對於閱讀者來講,形成閱讀過程的被迫中斷
-lambda表達式(匿名函數):
  -一個表達式,函數體相對簡單
  -不是一個代碼塊,僅僅是一個表達式
  -能夠有參數,有多個參數,用逗號隔開

#lambda表達式舉例:
  一、以lambda開頭
  二、緊跟必定的參數
  三、參數後用冒號和表達式隔開
  四、只是一個表達式,沒有return
#計算一個數字的100倍數
stm = lambda X:100*X
stm(89) #使用時跟函數調用同樣編程

 

##高階函數
-把函數做爲參數使用的函數,叫作高階函數
#函數名稱就是一個變量
def funcA():
  print(" In funcA")
funcB = funcA
funcB()
#以上代碼得出的結論:
  -函數名稱是變量
  -funcB 和 funcA只是名稱不一樣
  -既然函數名稱是變量,則能夠被當作參數傳入另外一個函數

#高級函數舉例閉包

#funcA是普通函數,返回一個傳入數字的100倍
def funcA(n):
  return n*100
#再寫一個函數,把傳入參數乘以300倍,利用高階函數
def funcB(n):
  #最終是想返回300n
  return funcA(n)#3
print(funcB(9))app

#寫一個高階函數
def funcD(n,f):
  #假設函數式把n擴大100倍
  return f(n)*3
print(funcD(9,funcA))

#比較上述,funcD比funcB更靈活編程語言


##系統高階函數
#map
-原意就是映射,把集合或者列表裏的元素,每一個元素都按照必定規則進行操做,生成一個新的列表或集合
-map函數是系統提供的具備映射功能的函數,返回值是一個迭代對象函數式編程

#map 舉例
#有一個列表,相對列表裏的每一個元素乘以10,並獲得新的列表函數

l1 = [i for i in range(10)]
print(l1)
def multi(n):
  return n*10
l2 = map(multi,11) #map類型是一個可迭代的結構,因此也能夠使用for循環
print(l2)    

 

#reduce
-原意是歸併,縮減
-把一個可迭代對象最後歸併成一個結果
-對於參數有要求:必須有兩個參數,必須有返回結果
-reduce([1,2,3,4,5]) == f(f(f(f(1,2),3),4),5)
-reduce 須要導入functools包spa

from functools import reduce
#定義一個操做函數
#假設操做函數是用來相加
def siqi(x,y):
  return x+y
#對於列表[1,2,3,4,5,6]執行siqi的reduce操做
rst = reduce(siqi,[1,2,3,4,5,6])
print(rst)

 

## filter 函數
-過濾函數:對一組數據進行過濾,符合條件的數據生成一個新的列表並返回
-跟map比較:
  -相同:都對列表的每個元素進行操做
  -不一樣:
    -map會生成一個跟原始列表相對應的新列表
    -filter只有符合條件的纔會留下
  -filter函數寫法:
    -利用給定函數進行判斷
    -返回值必定是布爾值
    -調用格式:filter(f,data),f是過濾函數,data是數據

#filter案例
#對於一個列表,對其進行過濾,偶數生成新列表
#須要定義過濾函數
#過濾函數要求有輸入,返回布爾值code

def siqi(a):
  return a%2 == 0
l = [1,2,3,4,5,7,23,56,445]
rst = filter(siqi,l)
#返回的filter內容是一個可迭代對象
print(rst)    
print([i for i in rst])

 

## 高階函數-排序
-把一個序列按照給定的算法進行排序
-key:在排序前對每個元素進行key函數運算

#排序案例-1
a = [234,546,234,56,765]
siqi = sorted(a,reverse=True)
print(siqi)

#排序案例-2
a = [234,546,234,56,765,-2354,-234]
#按照絕對值進行排序
#abs是求絕對值的意思
按照倒序排列
siqi = sorted(a,key=abs,reverse=True)
print(siqi)

#排序案例-3
astr = ["siqi","houzi","yong","qi"]
bstr = sorted(satr)
print(bstr)
cstr = sorted(astr,key=str.lower)
print(cstr)

 

## 返回函數
-函數能夠返回具體的值
-也能夠返回一個函數做爲結果

#定義一個普通函數
def pangqi(a):
  print("aihouzi")
  return None
a = pangqi(8)
print(8)
#函數做爲返回值返回,被返回的函數在函數體內定義
def qi1():
  def qi2():
    print("aihouzi")
    return 3
    return qi2    
#使用上面定義的函數
#調用qi1,返回一個函數qi2,賦值給qi3
qi3 = qi2()
print(qi3)
qi3()

#複雜一點的返回函數的例子

#args:參數列表
#一、F4定義函數,返回內部定義的函數F5
#二、F5使用了外部變量,這個變量是F4的參數
def F4(*args):
  def F5():
    rst = 0
    for n in args:
      rst += n
    return rst
  return F5

F6 = F4(1,2,3,4,5,6,7,8,9,0)
#F6的調用方式
F6()

 

##閉包(closure)
-當一個函數在內部定義函數,而且內部的函數應用外部函數的參數或者變量,當內部函數被當作返回值時,以前被應用的參數和變量保存在了返回的函數中,這種現象,稱爲閉包
-上述案例說明了閉包
-但返回閉包時,返回函數不能引用任何循環變量,如須要引用,必須在前面加一個函數固定住變量
#例

def count():
  l = []
  for i in range(3):
    def f(i):
      def g():
        return i
      return g
    l.append(f(i))
  return l

f1, f2, f3 = count()
print f1()
print f2()
print f3()

 

## 裝飾器
def hello():
  print("helloworld")
hello()
f = hello()
f()
# 如今有一個新的需求,
#對hello功能進行擴展,每次打印hello以前打印當前系統時間
#而實現這個功能,不能改動現有代碼
#此時使用裝飾器
-Decrator 裝飾器
-裝飾器的使用:使用@語法,@加函數名
代碼實現:

import time
def printTime(f):
  den wrapper(*args,**kwargs):
    print("Time:",time.ctime())
    return f(*args,**kwargs)
  return wrapper
#上面定義了裝飾器,使用的時候須要用到@,次付好是python的語法糖
@printTime
def hello():
  print("hello world")
hello()

#裝飾器的好處是一旦定義,則能夠裝飾任何函數
#一旦被其裝飾,則把裝飾器的功能直接添加到定義函數的功能上,
@printTime
def hello2():
  print("pangqi is stupid")
  print("houzi is clever")
hello2()    

 

 

## 偏函數
#把字符串轉化成十進制的數字
int("12345")
#八進制的字符串12345,把它表示成十進制
int("12345",base=8)

#新建一個函數,此函數默認輸入的字符串是十六進制
#把字符串返回成十進制
def int16(x,base=16):
return in(x,base)
int16("12345")

#偏函數定義
-參數固定的函數。至關於有一個特定參數的函數體
-functools.partial的做用是,把一個函數某些參數固定,返回新函數
import functools
#實現上面int16的功能
int16 = functools.partial(int,base=16)
int16("12345")


#補充高階函數
#zip

-把兩個可迭代內容生成一個可迭代的tuple元素類型組成的元組
# zip案例-1
l1 = [1,2,3,4,5]
l2 = [11,22,33,44,55]
z = zip(l1,l2)
print(zip)

for i in z:
  print(i)
# zip案例-2
l1 = ["siqi","houzi","haizi"]
l2 = [99,60,100]
z = zip(l1,l2)
for i in z:
  print(i)

 

 

# enumerate
-跟zip功能相似,對可迭代對象裏的每個元素,配上一個索引,而後索引和內容構成tuple類型
#enumerate案例-1

l1 = [11,22,33,44,55]
en = enumerate(l1)
l2 = [i for i in en]    
print(l2)

#enumerate案例-2
em = enumerate(l1,start=100)
l2 = [i for i in em]
print(l2)


#collections模塊
-namedtuple
-deque

 

#namedtuple

-tuple類型
-是一個可命名的tuple
import collections
Point = collections.namedtuple("Point",["x","y"])
p = Point(11,22)
print(p.x)
print(p[0])

 

#deque
-比較方便的解決了頻繁刪除插入帶來的效率問題

from collections import deque
q = deque(["a","b","c"])
print(q)
q.append("d")
print(q)
q.appendleft("x")
print(q)

 

#defaultdict
-當直接讀取dict不存在的屬性時,直接返回默認值

form collections import defaultdict
func = lambda:"siqi"
d2 = defaultdict(func)
d2 = {"one":1,"two":2,"three":3}
print(d["four"])

 

#Counter
-統計字符串個數

from collections import Counter
#須要括號裏可迭代
c = Counter("awdrdwrfocjswoad")
pring(c)
s = ["siqi","love","houzi"]
c = Counter(s)
print(c)
相關文章
相關標籤/搜索