python的高级应用
記錄一下Python**函數(shù)式編程,高級的幾個BIF**,高級官方庫方面的用法和心得。
函數(shù)式編程
函數(shù)式編程是使用一系列函數(shù)去解決問題,按照一般編程思維,面對問題時我們的思考方式是“怎么干”,而函數(shù)函數(shù)式編程的思考方式是我要“干什么”。很多好用的函數(shù)很大程度節(jié)約了編程成本。
函數(shù)參數(shù)問題
總結(jié)來說就三種基本的情況:
- fun(a,b)
- fun(a,*b):b是可迭代對象
- fun(a,**b):b是帶有檢索的迭代對象,在函數(shù)體內(nèi)部解析的時候類似字典
其他的情況基本是上面的改動,注意fun(*a,**b)這種形式是任意參數(shù)。
ls = [i for i in range(10)] def fun1(a,*b):for i in b:print(a,i) fun1(1,*ls)def fun2(name, age, **kw):print('name:', name, 'age:', age, 'other:', kw) fun2('AsuraDong',12,參數(shù)="random")匿名函數(shù):lambda
裝飾器:@
這種在代碼運行期間動態(tài)增加功能的方式,稱之為“裝飾器”(Decorator)。
沒有參數(shù)的裝飾器
# 定義一個裝飾器 def log(func):def wrapper(*args, **kw):print('call %s()' % func.__name__)return func(*args, **kw)return wrapper@log def now():print('2015-3-25')now()注意裝飾器的內(nèi)部邏輯關(guān)系(調(diào)用順序):log()->return wrapper -> wrapper() -> return func() -> now()
含參數(shù)的裝飾器
def log(text):def decorator(func):def wrapper(*args, **kw):print('%s %s():' % (text, func.__name__))return func(*args, **kw)return wrapperreturn decorator@log("可愛的參數(shù)") def now():print('2015-3-25')進一步完善:保留函數(shù)的內(nèi)置方法name不改變
如果調(diào)用now.__name__,得到的結(jié)果是wrapper而不是我們希望的now(本來函數(shù)的名字)。顯然這與我們的初衷相背離。這是需要在wrapper前面加上functools庫里的@functools.wraps(func)。
import functools def log(text):def decorator(func):@functools.wraps(func)def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__))return func(*args, **kw)return wrapperreturn decorator@log("可愛的參數(shù)") def now():print('2015-3-25')print(now.__name__)裝飾器用途
除了之前講的可以讓代碼更容易理解之外(但是確實不好寫),還有什么作用?本來我也覺得沒啥用。。。直到后來接觸NLTK,里面有一個@memorize裝飾器,在遞歸的時候可以自動保留每次的結(jié)果,避免了手動去完善代碼(可以去翻之前的博客)。所以用處還是很大的。
歡迎進一步交流本博文相關(guān)內(nèi)容:
博客園地址 : http://www.cnblogs.com/AsuraDong/
CSDN地址 : http://blog.csdn.net/asuradong
也可以致信進行交流 : xiaochiyijiu@163.com
歡迎轉(zhuǎn)載 , 但請指明出處 ?:??)
BIF:內(nèi)建的函數(shù)(built-in functions)
zip:將兩個迭代對象合成一個迭代對象
注意:多余的沒有匹配的迭代元素會被自動舍棄
a = [1,2,3] b = 'avsss' for i in zip(a,b):print(i) for i,j in zip(a,b):print('Index:',i,"; Item:",j)enumerate:返回的是迭代對象,由位置+元素構(gòu)成
for i,j in enumerate(b):print("Index:",i,":Item:",j)filter:過濾函數(shù)
兩個參數(shù),第一個是函數(shù),第二個是一個可迭代對象。返回的值是一個可迭代對象,其中的每個元素是參數(shù)中迭代對象的每個元素在參數(shù)中的函數(shù)返回值為True的元素。(有點亂,看代碼)
list(filter(lambda m:m%2==0,range(1,6)))結(jié)果是[2,4]
map:映射函數(shù)
用法和filter類似,區(qū)別如下:
- 參數(shù)里面的函數(shù)作用是對迭代對象每個元素操作
- 返回的被操作過的迭代對象
結(jié)果是[1, 4, 9, 16, 25]
reduce
- 在functools庫里
- func接收兩個參數(shù),reduce把結(jié)果繼續(xù)和序列的下一個元素做累積計算
sorted:排序函數(shù)
非常重要,主要是在對參數(shù)的調(diào)整上做工作,甚至可以實現(xiàn)對類對象的排序。
基本排序和倒序
默認(rèn)的排序是從小到大,如果需要從大到小,那么應(yīng)該修改reverse參數(shù)為True。
print(sorted([-1,0,-100],reverse = True)) print(sorted([-1,0,-100]))key參數(shù)
key參數(shù)來指定一個函數(shù),此函數(shù)將在每個元素比較前被調(diào)用。
sorted([-1,0,-100],key = abs,reverse = True)#對絕對值的大小進行排序student_tuples = [('john', 'A', 15),('jane', 'B', 12),('dave', 'B', 10), ] print(sorted(student_tuples, key=lambda student: student[2])) #按數(shù)字排序按照這個思路,可以實現(xiàn)對類的排序。當(dāng)然這是根據(jù)類中的某一類元素來進行的。
class Student:def __init__(self, name, grade, age):self.name = nameself.grade = gradeself.age = agedef __repr__(self):return repr((self.name, self.grade, self.age))student_objects = [Student('john', 'A', 15),Student('jane', 'B', 12),Student('dave', 'B', 10), ]sorted(student_objects, key=lambda student: student.age)多級排序
如果你想根據(jù)類里面的多個元素或者迭代對象中的多個元素來排序,那么就需要operator庫里面的兩個函數(shù)。應(yīng)該注意的是它們的參數(shù)對應(yīng)的是名字還是位置。并且排序為了避免二義性,都是先以第一個參數(shù)為基礎(chǔ)依次進行排序。
from operator import itemgetter,attrgetter class Student:def __init__(self, name, grade, age):self.name = nameself.grade = gradeself.age = agedef __repr__(self):return repr((self.name, self.grade, self.age))student_objects = [Student('john', 'A', 15),Student('jane', 'B', 12),Student('dave', 'B', 10), ] student_tuples = [('john', 'A', 15),('jane', 'B', 12),('dave', 'B', 10), ] print(sorted(student_objects, key=attrgetter('name','age'))) print(sorted(student_tuples, key=itemgetter(1,2)))高級官方庫
itertools
itertools模塊提供的全部是處理迭代功能的函數(shù),它們的返回值不是list,而是Iterator,只有用for循環(huán)迭代的時候才真正計算
itertools.count(start=0,step=1)
默認(rèn)是從0開始,間隔為1。
import itertools natuals = itertools.count(0) for i in natuals:print (i)這段代碼會一直打印下去,直到遇到終止。
itertools.cycle(iterator)
將iterator中的元素?zé)o限循環(huán)下去。
cc = itertools.cycle('456') for c in cc:print(c)itertools.repeat(obj[,最大重復(fù)次數(shù)])
將obj默認(rèn)無限重復(fù)。
np = itertools.repeat('1A.', 3) for i in np:print(i)itertools.chain(a,b,..,n,…)
將迭代器abc串聯(lián)起來,形成一個新的迭代器。
a = [1,2] b =[3,4] for i in itertools.chain(a,b):print(i)c = {"fef":1} for i in itertools.chain(a,b,c):print(i)itertools.groupby(iterator)
將iterator中相鄰的重復(fù)元素挑出來。所以,如果想對一個迭代對象查找不重復(fù)的元素,可以縣排序,再調(diào)用這個方法。
for i in itertools.groupby('ABCA'):print(i)itertools.takewhile(func,iterator)
無限序列雖然可以無限迭代下去,但是通常我們會通過takewhile()等函數(shù)根據(jù)條件判斷來截取出一個有限的序列
natuals = itertools.count(1) ns = itertools.takewhile(lambda x :x<=10,natuals) print(list(ns))組合生成器
| product() | p, q, … [repeat=1] | cartesian product, equivalent to a nested for-loop |
| permutations() | p[, r] | r-length tuples, all possible orderings, no repeated elements |
| combinations() | p, r | r-length tuples, in sorted order, no repeated elements |
| combinations_with_replacement() | p, r | r-length tuples, in sorted order, with repeated elements |
| product(‘ABCD’, repeat=2) | AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD | |
| permutations(‘ABCD’, 2) | AB AC AD BA BC BD CA CB CD DA DB DC | |
| combinations(‘ABCD’, 2) | AB AC AD BC BD CD | |
| combinations_with_replacement(‘ABCD’, 2) | AA AB AC AD BB BC BD CC CD DD |
collections
里面收集了很多常用的數(shù)據(jù)結(jié)構(gòu),例如計數(shù)器、隊列、順序字典等等。而這些很多繼承于基本的數(shù)據(jù)結(jié)構(gòu),所以可以調(diào)用對應(yīng)的BIF。
Counter:計數(shù)器
用法如下:
from collections import * c = Counter() for ch in 'this is a string':c[ch]+=1 #自動生成對應(yīng)的鍵和值,值默認(rèn)為0.每次出現(xiàn)則加1print(c)結(jié)果是:Counter({‘i’: 3, ‘s’: 3, ’ ‘: 3, ‘t’: 2, ‘h’: 1, ‘a(chǎn)’: 1, ‘r’: 1, ‘n’: 1, ‘g’: 1})
deque:隊列
高效實現(xiàn)插入和刪除操作的雙向列表,適合用于隊列和棧。如果數(shù)據(jù)量大而插入刪除操作又多,可以使用deque。并且他繼承了list的方法。
多出的兩種常用方法:
1. appendleft(obj):Add an element to the left side of the deque.
2. popleft():Remove and return the rightmost element.
namedtuple
namedtuple是一個函數(shù),它用來創(chuàng)建一個自定義的tuple對象,并且規(guī)定了tuple元素的個數(shù),并可以用屬性而不是索引來引用tuple的某個元素。這樣一來,我們用namedtuple可以很方便地定義一種數(shù)據(jù)類型,它具備tuple的不變性,又可以根據(jù)屬性來引用,使用十分方便。
我們知道tuple可以表示不變集合,例如,一個點的二維坐標(biāo)就可以表示成:p = (1,2)。但是,看到(1, 2),很難看出這個tuple是用來表示一個坐標(biāo)的。定義一個class又小題大做了,這時,namedtuple就派上了用場:
>>> from collections import namedtuple >>> Point = namedtuple('Point', ['x', 'y']) >>> p = Point(1, 2) >>> p.x 1 >>> p.y 2 >>> isinstance(p, Point) True >>> isinstance(p, tuple) Truedefaultdict:key不存在時的dict
from collections import defaultdict dd = defaultdict(lambda: 'N/A') #默認(rèn)值是調(diào)用函數(shù)返回的,而函數(shù)在創(chuàng)建defaultdict對象時傳入 dd['key1'] = 'abc' print(dd['key1']) print(dd['不存在的'])OrderedDict:留有順序的字典
順序是添加鍵值對的順序,這樣,在迭代的時候可以保持順序。并且可以實現(xiàn)先入先出等類似的字典對象。
from collections import OrderedDict d = dict([('a', 1), ('b', 2), ('c', 3)]) print(d) # dict的Key是無序的od = OrderedDict([('a', 1), ('b', 2), ('c', 3)]) print(od) # OrderedDict的Key是有序的總結(jié)
以上是生活随笔為你收集整理的python的高级应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 保护号码隐私(如:电话、身份证、Emai
- 下一篇: python机器学习笔记:ID3决策树算