亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python常見的反模式有哪些

發布時間:2021-07-06 18:22:48 來源:億速云 閱讀:139 作者:chen 欄目:編程語言

本篇內容介紹了“Python常見的反模式有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

1.對Iterable對象使用map()和filter()

內置的 map 和 filter 可以幫助我們通過函數編程的原理在 Python 中轉換 iterable 對象。

這兩個方法都接受一個函數和一個 iterable 作為參數,并返回相應的對象。

通過將該對象作為參數傳遞到 Python 中的內置列表構造函數,可以將其轉換為列表。

我們經常使用 lambda 函數作為 map、filter 函數的參數:

my_list = [1, 2, 3, 4 ,5, 6, 7, 8, 9, 10]  # 將每個元素乘以2 print(list(map(lambda x: x * 2, my_list)))  # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]  # 過濾掉偶數 print(list(filter(lambda x: x % 2 == 0, my_list)))  # [2, 4, 6, 8, 10]

上面的代碼看起來相當累贅和不清楚。使用列表理解可以實現相同結果:

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]  # 與map相同 print([x * 2 for x in my_list]) # [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]  # 與filter相同 print([x for x in my_list if x % 2 == 0]) # [2, 4, 6, 8, 10]

不使用lambda函數后,列表理解變得更具可讀性和簡潔性。

2.輸入較大時使用列表理解

列表理解有助于我們編寫出清晰、簡潔的代碼。

但是,列表理解總是為 iterable 中的每個值創建一個列表。當輸入量非常大時,就會導致內存占用過大的問題:我們的機器可能會崩潰。

生成器表達式結合了列表理解和生成器這兩個方面的優點,為處理大型輸入序列提供了更有效的方法。

要創建生成器表達式,只需將列表中的 [] 方括號替換為()方括號。

Python常見的反模式有哪些

生成器表達式并不是創建一個全新的列表,而是創建一個迭代器。

這會降低創建速度并優化內存分配。我們可以使用 next 函數或通過循環訪問生成器表達式的每個后續元素。

my_list = [1, 2, 3, 4 ,5, 6, 7, 8, 9, 10]  my_gen_expr = (x * 2 for x in my_list)  print(next(my_gen_expr)) print(next(my_gen_expr)) # >> # 2 # 4  for x in my_gen_expr:   print(x) # >> # 6 # 8 # 10 # 12 # 14 # 16 # 18 # 20

注:生成器表達式是有狀態的,因此在重用時要注意。如果要多次使用迭代器,則可能需要重新創建迭代器。

3.不使用range()的情況

range 函數對迭代整數很有用。

for i in range(10):     print(i)

當迭代類似列表的數據結構時,我們可以完全依賴for循環語法來訪問每個項目。代碼如下:

my_list = [2, 4, 6, 8, 10]  for item in my_list:     print(item)  # Output: # 2 # 4 # 6 # 8 # 10

但是,當想要訪問索引和元素時,我們可以使用列表長度下的 range 方法,如下所示:

my_list = [2, 4, 6, 8, 10]  for i in range(len(my_list)):     print("index: ", i, "value: ", my_list[i])      # Output: # index: 0 value: 2 # index: 1 value: 4 # index: 2 value: 6 # index: 3 value: 8 # index: 4 value: 10

代碼看起來不可讀,因為我們必須在列表上調用 len,然后使用 range 方法包裝輸出。為了使代碼更加具有 python  風格,我們必須提高代碼的可讀性。

更好的方法是對 list 對象調用 enumerate 函數。這將創建一個生成器,生成列表項的索引和值。

my_list = [2, 4, 6, 8, 10]  for i, v in enumerate(my_list):     print("index: ", i, "value: ", v)      # Output: # index: 0 value: 2 # index: 1 value: 4 # index: 2 value: 6 # index: 3 value: 8 # index: 4 value: 10

代碼看起來是不是更加干凈了?

4.字典中鍵丟失的問題

字典具有快速訪問、分配、插入和刪除的能力,是一種非常流行的數據結構。

但是新手開發人員訪問字典中不存在的密鑰時經常會遇到問題。

crypto_price = {   "Bitcoin": 64000,   "Ethereum": 2300,   "Dogecoin": 0.12 }  crypto_price["XRP"]
Python常見的反模式有哪些

處理該類問題的其中一種方法是檢查字典中是否存在密鑰,代碼如下:

key = "XRP"  if key not in crypto_price:     crypto_price[key] = 1.2      print(crypto_price[key])

另一種方法是使用 try/except 塊,如下所示:

key = "XRP"  try:     xrp = crypto_price[key] except raise KeyError:     xrp = 1.2      crypto_price[key] = xrp

上面的代碼確實實現了我們的目標,但是我們可以通過使用字典方法 get 進一步改進。

通過使用 get 方法來獲取相應鍵的值,而不是使用方括號 [] 來訪問字典的鍵。

另外,如果鍵不存在,get 方法將返回 None,而不是拋出 KeyError。如果缺少鍵而不是無鍵,還可以將參數傳遞給 get  方法以獲取默認值。

key = "XRP"  if crypto_price.get("XRP") is None:   crypto_price["XRP"] = 1.2
ada = crypto_price.get("ADA", 0)  # Prints 0 print(ada)

5.惰性關鍵字和位置參數設計

Python函數能夠同時接受位置參數和關鍵字參數。

位置參數是不后跟等號(=)和默認值的名稱。

關鍵字參數后面跟一個等號和一個給出其默認值的表達式。

得益于這種設計,python函數的創建和重用非常靈活。

但是,定義函數時,錯誤的設計選擇可能會導致代碼中難以修復的錯誤。

我們以計算復利的函數為例:

# 復利計算器年/月復利 def calculate_compound_interest(principal, rate, time_in_years,                                 compounded_monthly, to_string):   t = 1   if compounded_monthly:     t = 12   amt = principal * (1 + rate/(t * 100)) ** (time_in_years * t)   if to_string:     return f"${amt - principal:.2f}"    return amt - principal          calculate_compound_interest(100, 5, 2, False, False)   # 10.25

調用函數時出現的一個問題是,兩個布爾參數(compounded_monthly 和結尾的  to_string)很容易相互混淆。這就會出現難以追蹤的問題。

我們可以通過如下方式更改函數定義來提高可讀性:

# 復利計算器年/月復利 def calculate_compound_interest(principal, rate, time_in_years,                                 compounded_monthly=False, to_string=False):

通過將兩個布爾參數指定為關鍵字參數,函數調用方可以顯式地指定要設置的布爾值,這些值將覆蓋默認值。

calculate_compound_interest(100, 5, 2, compounded_monthly=True) # 10.49413355583269  calculate_compound_interest(100, 5, 2, to_string=True) # '$10.25'

但是,這仍然會出現問題,主要原因是關鍵字參數是可選的,因為沒有任何強制調用方將這些作為關鍵字參數使用。

因此,我們仍然可以使用舊方法調用該函數:

calculate_compound_interest(100, 5, 2, False, False)

解決該問題的方法是僅在定義函數時強制布爾參數為關鍵字:

# 復利計算器年/月復利 def calculate_compound_interest(principal, rate, time_in_years, *, # Changed                                 compounded_monthly=False, to_string=False):

我們看到,*符號表示位置參數的結束和僅關鍵字參數的開始。

如果這樣調用:

calculate_compound_interest(100, 5, 2, False, False)

將發生以下錯誤:

--------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-32-faf75d2ad121> in <module> ----> 1 print(calculate_compound_interest(1000, 5, 2, False, False)) TypeError: calculate_compound_interest() takes 3 positional arguments but 5 were given

但是,關鍵字參數及其默認行為仍將保持不變,如下所示:

alculate_compound_interest(100, 5, 2, compounded_monthly=True) # 10.49413355583269  calculate_compound_interest(100, 5, 2, to_string=True) # '$10.25'

然而,仍然存在一個問題。

假設調用者決定對前三個必需參數(principal、rate、time in years)混合使用位置和關鍵字。

如果這三個參數的函數參數名稱發生更改,我們將看到Python解釋器。它會這樣說:

# 復利計算器年/月復利 def calculate_compound_interest(p, r, t_in_y, *, # Changed                                 compounded_monthly=False, to_string=False):
calculate_compound_interest(principal=1000, rate=5, time_in_years=2)  calculate_compound_interest(1000, 5, time_in_years=2)

將發生以下錯誤:

--------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-36-42e7ec842cd5> in <module> ----> 1 calculate_compound_interest(principal=1000, rate=5, time_in_years=2) TypeError: calculate_compound_interest() got an unexpected keyword argument 'principal' --------------------------------------------------------------------------- TypeError                                 Traceback (most recent call last) <ipython-input-37-1bc57c40980f> in <module> ----> 1 calculate_compound_interest(1000, 5, time_in_years=2) TypeError: calculate_compound_interest() got an unexpected keyword argument 'time_in_years'

因為我們沒有考慮調用方顯式地使用位置參數,所以代碼中斷。

python3.8中引入了一個解決方案,我們可以使用/參數重新定義函數,該參數指示僅位置參數的結束位置。代碼如下:

# 復利計算器年/月復利 def calculate_compound_interest(p, r, t_in_y, /, *,  # 改變                                 compounded_monthly=False, to_string=False):

現在這樣調用函數就會產生正確的結果:

calculate_compound_interest(100, 5, 2, compounded_monthly=True) # 10.49413355583269  calculate_compound_interest(100, 5, 2, to_string=True) # '$10.25'

但是,如果我們這樣調用:

calculate_compound_interest(p=1000, r=5, t_in_y=2)

也會顯示相應的錯誤:

---------------------------------------------------------------------------  TypeError                                 Traceback (most recent call last)  <ipython-input-21-883e876a7e8b> in <module>  ----> 1 calculate_compound_interest(p=1000, r=5, t_in_y=2)        2  TypeError: calculate_compound_interest() got some positional-only arguments passed as keyword arguments: 'p, r, t_in_y'

“Python常見的反模式有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南岸区| 武平县| 长春市| 襄汾县| 南涧| 上虞市| 交口县| 剑河县| 阿拉善盟| 威宁| 明光市| 自贡市| 方正县| 武鸣县| 汾阳市| 石门县| 剑川县| 米易县| 凤冈县| 镇康县| 湛江市| 枞阳县| 铜陵市| 肃宁县| 左云县| 铜川市| 黄石市| 定兴县| 叶城县| 陆川县| 台东市| 酒泉市| 阳新县| 峨边| 平邑县| 抚顺市| 个旧市| 大余县| 芮城县| 安岳县| 临城县|