Python有哪些高級用法?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
列表推導(list comprehensions)
場景1:將一個三維列表中所有一維數據為a的元素合并,組成新的二維列表。
最簡單的方法:新建列表,遍歷原三維列表,判斷一維數據是否為a,若為a,則將該元素append至新列表中。
缺點:代碼太繁瑣,對于Python而言,執行速度會變慢很多。
針對場景1,我們首先應該想到用列表解析式來解決處理,一行代碼即可解決:
lista = [item for item in array if item[0] == 'a']
那么,何為列表解析式?
官方解釋:列表解析式是Python內置的非常簡單卻強大的可以用來創建list的生成式。
強大具體如何體現?
可以看到,使用列表解析式的寫法更加簡短,除此之外,因為是Python內置的用法,底層使用C語言實現,相較于編寫Python代碼而言,運行速度更快。
場景2: 對于一個列表,既要遍歷索引又要遍歷元素。
這里可以使用Python內建函數enumerate,在循環中更好的獲取獲得索引。
array = ['I', 'love', 'Python'] for i, element in enumerate(array): array[i] = '%d: %s' % (i, seq[i])
可以使用列表推導式對其進行重構:
def getitem(index, element): return '%d: %s' % (index, element) array = ['I', 'love', 'Python'] arrayIndex = [getitem(index, element) for index, element in enumerate(array)]
據說這種寫法更加的Pythonic。
總結:如果要對現有的可迭代對象做一些處理,然后生成新的列表,使用列表推導式將是最便捷的方法。
迭代器和生成器
迭代器(Iterator)
這里的迭代可以指for循環,在Python中,對于像list,dict和文件等而言,都可以使用for循環,但是它們并不是迭代器,它們屬于可迭代對象。
什么可迭代對象
最簡單的解釋:可以使用for...in...語句進行循環的對象,就是可迭代對象(Iterable),可以使用isinstance()方法進行判斷。
from collections import Iterable
type = isinstance('python', Iterable)
print type什么是迭代器
迭代器指的是可以使用next()方法來回調的對象,可以對可迭代對象使用iter()方法,將其轉換為迭代器。
temp = iter([1, 2, 3]) print type(temp) print next(temp)
此時temp就是一個迭代器。所以說,迭代器基于兩個方法:
next:返回下一個項目
iter 返回迭代器本身
可理解為可被next()函數調用并不斷返回下一個值的對象就是迭代器,在定義一個裝飾器時將需要同時定義這兩個方法。
迭代器的優勢
在構建迭代器時,不是將所有的元素一次性的加載,而是等調用next方法時返回元素,所以不需要考慮內存的問題。
迭代器應用場景
那么,具體在什么場景下可以使用迭代器呢?
數列的數據規模巨大
數列有規律,但是不能使用列表推導式描述。
生成器
生成器是一種高級迭代器,使得需要返回一系列元素的函數所需的代碼更加的簡單和高效(不像創建迭代器代碼那般冗長)。
生成器函數
生成器函數基于yield指令,可以暫停一個函數并返回中間結果。當需要一個將返回一個序列或在循環中執行的函數時,就可以使用生成器,因為當這些元素被傳遞到另一個函數中進行后續處理時,一次返回一個元素可以有效的提升整體性能。
常見的應用場景是使用生成器的流數據緩沖區。
生成器表達式
生成式表達式是一種實現生成器的便捷方式,將列表推導式的中括號替換為圓括號。
和列表推導式的區別:列表生成式可以直接創建一個表,但是生成器表達式是一種邊循環邊計算,使得列表的元素可以在循環過程中一個個的推算出來,不需要創建完整的列表,從而節省了大量的空間。
g = (x * x for x in range(10))
總結:生成器是一種高級迭代器。生成器的優點是延遲計算,一次返回一個結果,這樣非常適用于大數據量的計算。但是,使用生成器必須要注意的一點是:生成器只能遍歷一次。
lambda表達式(匿名函數)
lambda表達式純粹是為了編寫簡單函數而設計,起到了一個函數速寫的作用,使得簡單函數可以更加簡潔的表示。
lambda和def的區別
lambda表達式可以省去定義函數的過程,讓代碼更加的簡潔,適用于簡單函數,編寫處理更大業務的函數需要使用def定義。
lambda表達式常搭配map(), reduce(), filter()函數使用
map(): map函數接受兩個參數,一個是函數,一個是序列,其中,函數可以接收一個或者多個參數。map將傳入的函數依次作用于序列中的每個元素,將結果作為新的列表返回。
#將一個列表中的數字轉換為字符串 map(str, [1,2,3,4,5,6])
reduce():函數接收兩個參數,一個是函數,另一個是序列,但是,函數必須接收兩個參數reduce把結果繼續和序列的下一個元素做累積計算,其效果就是reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)。
filter():該函數用于篩選,將傳入的函數,依次作用于每個元素,然后根據函數的返回值是True還是False,決定是留下還是丟棄該元素。
裝飾器
裝飾器本質是一個Python函數,它可以讓其它函數在沒有任何代碼變動的情況下增加額外功能。有了裝飾器,我們可以抽離出大量和函數功能本身無關的雷同代碼并繼續重用。經常用于具有切面需求的場景:包括插入日志、性能測試、事務處理、緩存和權限校驗等。
那么為什么要引入裝飾器呢?
場景:計算一個函數的執行時間。
一種方法就是定義一個函數,用來專門計算函數的運行時間,然后運行時間計算完成之后再處理真正的業務代碼,代碼如下:
import time def get_time(func): startTime = time.time() func() endTime = time.time() processTime = (endTime - startTime) * 1000 print "The function timing is %f ms" %processTime def myfunc(): print "start func" time.sleep(0.8) print "end func" get_time(myfunc) myfunc()
但是這段代碼的邏輯破壞了原有的代碼邏輯,就是對所有func函數的調用都需要使用get_time(func)來實現。
那么,有沒有更好的展示方式呢?當然有,那就是裝飾器。
編寫簡單裝飾器
結合上述實例,編寫裝飾器:
def get_time(func): def wrapper(): startTime = time.time() func() endTime = time.time() processTime = (endTime - startTime) * 1000 print "The function timing is %f ms" %processTime return wrapper print "myfunc is:", myfunc.__name__ myfunc = get_time(myfunc) print "myfunc is: ", myfunc.__name__ myfunc()
這樣,一個簡單的完整的裝飾器就實現了,可以看到,裝飾器并沒有影響函數的執行邏輯和調用。
在Python中,可以使用"@"語法糖來精簡裝飾器的代碼,將上例更改為:
@ get_time def myfunc(): print "start func" time.sleep(0.8) print "end func" print "myfunc is: ", myfunc.__name__ myfunc()
** 裝飾器的調用順序**
裝飾器可以疊加使用,若多個裝飾器同時裝飾一個函數,那么裝飾器的調用順序和@語法糖的聲明順序相反,也就是:
@decorator1 @decorator2 def func(): pass
等效于:
func = decorator1(decorator2(func()))
被裝飾的函數帶參數
上述實例中,myfunc()是沒有參數的,那如果添加參數的話,裝飾器該如何編寫呢?
#被裝飾的函數帶參數 def get_time3(func): def wrapper(*args, **kwargs): startTime = time.time() func(*args, **kwargs) endTime = time.time() processTime = (endTime - startTime) * 1000 print "The function timing is %f ms" %processTime return wrapper @ get_time3 def myfunc2(a): print "start func" print a time.sleep(0.8) print "end func" a = "test" myfunc2(a)
帶參數的裝飾器
裝飾器有很大的靈活性,它本身支持參數,例如在上述實例中,@get_time裝飾器唯一的參數就是執行業務的函數,當然也可以在裝飾器中添加參數,加以邏輯判斷。
內置裝飾器
Python中,常見的類裝飾器包括:@staticmathod、@classmethod和@property
@staticmethod:類的靜態方法,跟成員方法的區別是沒有self參數,并且可以在類不進行實例化的情況下調用。
@classmethod:跟成員方法的區別是接收的第一個參數不是self,而是cls(當前類的具體類型)
@property:表示可以直接通過類實例直接訪問的信息。
python的五大特點:1.簡單易學,開發程序時,專注的是解決問題,而不是搞明白語言本身。2.面向對象,與其他主要的語言如C++和Java相比, Python以一種非常強大又簡單的方式實現面向對象編程。3.可移植性,Python程序無需修改就可以在各種平臺上運行。4.解釋性,Python語言寫的程序不需要編譯成二進制代碼,可以直接從源代碼運行程序。5.開源,Python是 FLOSS(自由/開放源碼軟件)之一。
關于Python有哪些高級用法問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。