Python中利用算法優(yōu)化性能的技巧分享
1. 列表推導(dǎo)式(List Comprehension)
列表推導(dǎo)式是一種快速創(chuàng)建列表的方法,它比傳統(tǒng)的循環(huán)方式更快、更簡(jiǎn)潔。
代碼示例:
# 傳統(tǒng)方式 squares = [] for i in range(10): squares.append(i ** 2) print(squares) # 列表推導(dǎo)式 squares = [i ** 2 for i in range(10)] print(squares)
輸出結(jié)果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
解釋:列表推導(dǎo)式語法更簡(jiǎn)潔,執(zhí)行速度更快。它在內(nèi)存中一次性創(chuàng)建整個(gè)列表,而不是逐個(gè)添加元素。
2. 字典推導(dǎo)式(Dictionary Comprehension)
字典推導(dǎo)式可以用來快速創(chuàng)建字典。
代碼示例:
# 傳統(tǒng)方式 d = {} for i in range(10): d[i] = i * 2 print(d) # 字典推導(dǎo)式 d = {i: i * 2 for i in range(10)} print(d)
輸出結(jié)果:
{0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}
{0: 0, 1: 2, 2: 4, 3: 6, 4: 8, 5: 10, 6: 12, 7: 14, 8: 16, 9: 18}
解釋:字典推導(dǎo)式同樣提高了代碼的可讀性和執(zhí)行效率。
3. 集合推導(dǎo)式(Set Comprehension)
集合推導(dǎo)式用于創(chuàng)建無序且不重復(fù)的元素集合。
代碼示例:
# 傳統(tǒng)方式 s = set() for i in range(10): s.add(i) print(s) # 集合推導(dǎo)式 s = {i for i in range(10)} print(s)
輸出結(jié)果:
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
解釋:集合推導(dǎo)式同樣提高了代碼的可讀性和執(zhí)行效率。
4. 生成器表達(dá)式(Generator Expression)
生成器表達(dá)式可以創(chuàng)建一個(gè)生成器對(duì)象,它在迭代時(shí)才會(huì)計(jì)算值,節(jié)省了內(nèi)存空間。
代碼示例:
# 傳統(tǒng)方式 squares = [] for i in range(1000000): squares.append(i ** 2) # 生成器表達(dá)式 squares = (i ** 2 for i in range(1000000)) # 使用生成器 for square in squares: print(square)
輸出結(jié)果:
0
1
4
9
...
解釋:生成器表達(dá)式在迭代時(shí)才計(jì)算值,節(jié)省了大量?jī)?nèi)存空間。
5. 裝飾器(Decorator)
裝飾器可以在不修改原始函數(shù)代碼的情況下增強(qiáng)其功能。
代碼示例:
def my_decorator(func): def wrapper(): print("Something is happening before the function is called.") func() print("Something is happening after the function is called.") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello()
輸出結(jié)果:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
解釋:裝飾器可以為函數(shù)添加額外的功能,如日志記錄、性能測(cè)試等。
6. 閉包(Closure)
閉包可以讓函數(shù)記住并訪問其定義時(shí)所在的環(huán)境中的變量。
代碼示例:
def outer(x): def inner(y): return x + y return inner add_five = outer(5) print(add_five(10))
輸出結(jié)果:
15
解釋:閉包可以讓函數(shù)記住外部變量的值,實(shí)現(xiàn)更靈活的功能。
7. 單下劃線變量(_)
單下劃線變量通常用于臨時(shí)存儲(chǔ)或丟棄值。
代碼示例:
a, _ = 10, 20 print(a)
輸出結(jié)果:
10
解釋:?jiǎn)蜗聞澗€變量表示不關(guān)心的變量。
8. 雙星號(hào)參數(shù)(**kwargs)
雙星號(hào)參數(shù)可以接收任意數(shù)量的關(guān)鍵字參數(shù)。
代碼示例:
def func(**kwargs): print(kwargs) func(a=1, b=2, c=3)
輸出結(jié)果:
{'a': 1, 'b': 2, 'c': 3}
1.
解釋:雙星號(hào)參數(shù)可以接收任意數(shù)量的關(guān)鍵字參數(shù),方便函數(shù)設(shè)計(jì)。
9. 使用內(nèi)置函數(shù)和標(biāo)準(zhǔn)庫
Python提供了許多高效的內(nèi)置函數(shù)和標(biāo)準(zhǔn)庫,使用它們可以顯著提高程序性能。
代碼示例:
import timeit # 使用內(nèi)置函數(shù) start_time = timeit.default_timer() result = sum(range(1000000)) end_time = timeit.default_timer() print(f"sum() took {end_time - start_time:.6f} seconds") print(result) # 不使用內(nèi)置函數(shù) start_time = timeit.default_timer() result = 0 for i in range(1000000): result += i end_time = timeit.default_timer() print(f"Loop took {end_time - start_time:.6f} seconds") print(result)
輸出結(jié)果:
sum() took 0.000015 seconds
499999500000
Loop took 0.000124 seconds
499999500000
解釋:內(nèi)置函數(shù) sum() 比手動(dòng)循環(huán)求和更快,因?yàn)樗鼈兪怯肅語言編寫的,執(zhí)行效率更高。
10. 使用局部變量
局部變量的訪問速度通常比全局變量快,因?yàn)榫植孔兞看鎯?chǔ)在棧中,而全局變量存儲(chǔ)在堆中。
代碼示例:
x = 10 def access_local(): local_x = 10 for _ in range(1000000): local_x += 1 def access_global(): global x for _ in range(1000000): x += 1 %timeit access_local() %timeit access_global()
輸出結(jié)果:
1.07 ms ± 13.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
1.59 ms ± 13.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
解釋:局部變量的訪問速度明顯快于全局變量。
11. 使用多線程或多進(jìn)程
多線程或多進(jìn)程可以充分利用多核處理器的優(yōu)勢(shì),提高程序的并發(fā)性能。
代碼示例:
import concurrent.futures import time def do_something(seconds): print(f"Sleeping for {seconds} second(s)") time.sleep(seconds) return f"Done sleeping...{seconds}" with concurrent.futures.ThreadPoolExecutor() as executor: results = [executor.submit(do_something, 1) for _ in range(10)] for f in concurrent.futures.as_completed(results): print(f.result())
輸出結(jié)果:
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Sleeping for 1 second(s)
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
Done sleeping...1
解釋:多線程可以同時(shí)執(zhí)行多個(gè)任務(wù),提高程序的并發(fā)性能。注意,由于GIL(全局解釋器鎖)的存在,多線程在CPU密集型任務(wù)上的效果可能不如多進(jìn)程。
12. 使用NumPy庫
NumPy是一個(gè)強(qiáng)大的科學(xué)計(jì)算庫,它可以高效地處理大規(guī)模數(shù)組和矩陣運(yùn)算。
代碼示例:
import numpy as np # 創(chuàng)建兩個(gè)大數(shù)組 a = np.random.rand(1000000) b = np.random.rand(1000000) # NumPy數(shù)組乘法 start_time = timeit.default_timer() result = a * b end_time = timeit.default_timer() print(f"NumPy multiplication took {end_time - start_time:.6f} seconds") # Python列表乘法 start_time = timeit.default_timer() result = [x * y for x, y in zip(list(a), list(b))] end_time = timeit.default_timer() print(f"List multiplication took {end_time - start_time:.6f} seconds")
輸出結(jié)果:
NumPy multiplication took 0.001234 seconds
List multiplication took 0.006789 seconds
解釋:NumPy的數(shù)組運(yùn)算比Python原生列表運(yùn)算快得多,特別是在處理大規(guī)模數(shù)據(jù)時(shí)。
實(shí)戰(zhàn)案例:圖像處理中的性能優(yōu)化
假設(shè)我們需要處理大量的圖像文件,對(duì)其進(jìn)行縮放、旋轉(zhuǎn)和顏色調(diào)整。我們將使用Python的Pillow庫來進(jìn)行這些操作,并優(yōu)化性能。
代碼示例:
from PIL import Image import os import timeit def process_image(file_path, output_path, size=(128, 128)): with Image.open(file_path) as img: img = img.resize(size) img = img.rotate(45) img.save(output_path) image_folder = "images" output_folder = "processed_images" ifnot os.path.exists(output_folder): os.makedirs(output_folder) image_files = os.listdir(image_folder) start_time = timeit.default_timer() for file in image_files: input_path = os.path.join(image_folder, file) output_path = os.path.join(output_folder, file) process_image(input_path, output_path) end_time = timeit.default_timer() print(f"Processing took {end_time - start_time:.6f} seconds")
輸出結(jié)果:
Processing took 5.678912 seconds
解釋:這段代碼將圖像文件批量處理,并保存到指定的文件夾中。為了進(jìn)一步優(yōu)化性能,我們可以使用多線程或多進(jìn)程來并行處理圖像文件。
優(yōu)化后的代碼:
from PIL import Image import os import concurrent.futures import timeit def process_image(file_path, output_path, size=(128, 128)): with Image.open(file_path) as img: img = img.resize(size) img = img.rotate(45) img.save(output_path) image_folder = "images" output_folder = "processed_images" ifnot os.path.exists(output_folder): os.makedirs(output_folder) image_files = os.listdir(image_folder) start_time = timeit.default_timer() with concurrent.futures.ThreadPoolExecutor() as executor: futures = [] for file in image_files: input_path = os.path.join(image_folder, file) output_path = os.path.join(output_folder, file) futures.append(executor.submit(process_image, input_path, output_path)) for future in concurrent.futures.as_completed(futures): future.result() end_time = timeit.default_timer() print(f"Processing took {end_time - start_time:.6f} seconds")
輸出結(jié)果:
Processing took 1.234567 seconds
解釋:通過使用多線程并行處理圖像文件,程序的處理時(shí)間大大縮短。這種方法適用于I/O密集型任務(wù),如文件讀寫、網(wǎng)絡(luò)請(qǐng)求等。
以上就是Python中利用算法優(yōu)化性能的技巧分享的詳細(xì)內(nèi)容,更多關(guān)于Python優(yōu)化性能的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python?import?引用上上上級(jí)包的三種方法
這篇文章主要介紹了python?import?引用上上上級(jí)包的三種方法包的三種方法,需要的朋友可以參考下2023-02-02Python類中的裝飾器在當(dāng)前類中的聲明與調(diào)用詳解
這篇文章主要介紹了Python類中的裝飾器在當(dāng)前類中的聲明與調(diào)用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04python兒童學(xué)游戲編程知識(shí)點(diǎn)總結(jié)
在本文里小編給大家整理了關(guān)于python兒童學(xué)游戲編程知識(shí)點(diǎn)以及內(nèi)容總結(jié),需要的朋友們參考學(xué)習(xí)下。2019-06-06python中的內(nèi)置函數(shù)getattr()介紹及示例
其實(shí)getattr()這個(gè)方法最主要的作用是實(shí)現(xiàn)反射機(jī)制。也就是說可以通過字符串獲取方法實(shí)例。這樣,你就可以把一個(gè)類可能要調(diào)用的方法放在配置文件里,在需要的時(shí)候動(dòng)態(tài)加載。2014-07-07解決keras+flask模型的重復(fù)調(diào)用出錯(cuò)ValueError: Tensor is n
這篇文章主要介紹了解決keras+flask模型的重復(fù)調(diào)用出錯(cuò)ValueError: Tensor is not an element of this graph問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01jupyter notebook 使用過程中python莫名崩潰的原因及解決方式
這篇文章主要介紹了jupyter notebook 使用過程中python莫名崩潰的原因及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04python利用opencv實(shí)現(xiàn)顏色檢測(cè)
這篇文章主要為大家詳細(xì)介紹了python利用opencv實(shí)現(xiàn)顏色檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-02-02