成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Python高能小技巧:用海象操作符減少重復(fù)代碼

開發(fā) 后端
賦值表達(dá)式(assignment expression)是Python 3.8新引入的語法,它會用到海象操作符(walrus operator)。這種寫法可以解決某些持續(xù)已久的代碼重復(fù)問題。a = b是一條普通的賦值語句,讀作a equals b,而a := b則是賦值表達(dá)式,讀作a walrus b。

 a = b是一條普通的賦值語句,讀作a equals b,而a := b則是賦值表達(dá)式,讀作a walrus b。這個符號為什么叫walrus呢?因為把:=順時針旋轉(zhuǎn)90°之后,冒號就是海象的一雙眼睛,等號就是它的一對獠牙。

 

[[391256]]

 

這種表達(dá)式很有用,可以在普通的賦值語句無法應(yīng)用的場合實現(xiàn)賦值,例如可以用在條件表達(dá)式的if語句里面。賦值表達(dá)式的值,就是賦給海象操作符左側(cè)那個標(biāo)識符的值。

舉個例子。如果有一筐新鮮水果要給果汁店做食材,那我們就可以這樣定義其中的內(nèi)容:

 

  1. fresh_fruit = { 
  2.     'apple': 10, 
  3.     'banana': 8, 
  4.     'lemon': 5, 

 

顧客點檸檬汁之前,我們先得確認(rèn)現(xiàn)在還有沒有檸檬可以榨汁。所以,要先查出檸檬的數(shù)量,然后用if語句判斷它是不是非零的值。

 

  1. def make_lemonade(count): 
  2.     print(f'Making {count} lemons into lemonade'
  3.  
  4. def out_of_stock(): 
  5.     print('Out of stock!'
  6.  
  7. count = fresh_fruit.get('lemon', 0) 
  8. if count
  9.     make_lemonade(count
  10. else
  11.     out_of_stock() 

 

這段代碼看上去雖然簡單,但還是顯得有點兒松散,因為count變量雖然定義在整個if/else結(jié)構(gòu)之上,然而只有if語句才會用到它,else塊根本就不需要使用這個變量。所以,這種寫法讓人誤以為count是個重要的變量,if和else都要用到它,但實際上并非如此。

我們在Python里面經(jīng)常要先獲取某個值,然后判斷它是否非零,如果是就執(zhí)行某段代碼。對于這種用法,我們以前總是要通過各種技巧,來避免count這樣的變量重復(fù)出現(xiàn)在代碼之中,這些技巧有時會讓代碼變得比較難懂。Python引入賦值表達(dá)式正是為了解決這樣的問題。下面改用海象操作符來寫:

 

  1. if count := fresh_fruit.get('lemon', 0): 
  2.     make_lemonade(count
  3. else
  4.     out_of_stock() 

 

新代碼雖然只省了一行,但讀起來卻清晰很多,因為這種寫法明確體現(xiàn)出count變量只與if塊有關(guān)。這個賦值表達(dá)式先把:=右邊的值賦給左邊的count變量,然后對自身求值,也就是把變量的值當(dāng)成整個表達(dá)式的值。

由于表達(dá)式緊跟著if,程序會根據(jù)它的值是否非零來決定該不該執(zhí)行if塊。這種先賦值再判斷的做法,正是海象操作符想要表達(dá)的意思。

檸檬汁效力強(qiáng),所以只需要一顆檸檬就能做完這份訂單,這意味著程序只需判斷非零即可。如果客人點的是蘋果汁,那就至少得用四個蘋果才行。按照傳統(tǒng)的寫法,要先從fresh_fruit這個字典里面查出蘋果(apple)的數(shù)量(count),然后在if語句里,根據(jù)這個數(shù)量構(gòu)造條件表達(dá)式(count >= 4)。

 

  1. def make_cider(count): 
  2.     print(f'Making cider with {count} apples'
  3.  
  4. count = fresh_fruit.get('apple', 0) 
  5. if count >= 4: 
  6.     make_cider(count
  7. else
  8.     out_of_stock() 

 

這段代碼與剛才那個檸檬汁的例子一樣,也過分突出了count變量的意義。下面改用海象操作符,把代碼寫得更清晰一些。

 

  1. if (count := fresh_fruit.get('apple', 0)) >= 4: 
  2.     make_cider(count
  3. else
  4.     out_of_stock() 

 

與剛才那個例子一樣,修改之后的代碼也比原來少了一行。但是這次,我們還要注意另外一個現(xiàn)象:賦值表達(dá)式本身是放在一對括號里面的。為什么要這樣做呢?因為我們要在if語句里面把這個表達(dá)式的結(jié)果跟4這個值相比較。

剛才檸檬汁的例子沒有加括號,因為那時只憑賦值表達(dá)式本身的值就能決定if/else的走向:只要表達(dá)式的值不是0,程序就進(jìn)入if分支。但是這次不行,這次要把這個賦值表達(dá)式放在更大的表達(dá)式里面,所以必須用括號把它括起來。當(dāng)然,在沒有必要加括號的情況下,還是盡量別加括號比較好。

還有一種類似的邏輯也會出現(xiàn)剛才說的重復(fù)代碼,這指的是:我們要根據(jù)情況給某個變量賦予不同的值,緊接著要用這個變量做參數(shù)來調(diào)用某個函數(shù)。

例如,若顧客要點香蕉冰沙,那我們首先得把香蕉切成好幾份,然后用其中的兩份來制作這道冰沙。如果不夠兩份,那就拋出香蕉不足(OutOfBananas)異常。下面用傳統(tǒng)的寫法實現(xiàn)這種邏輯:

 

  1. def slice_bananas(count): 
  2.     print(f'Slicing {count} bananas'
  3.     return count * 4 
  4.  
  5. class OutOfBananas(Exception): 
  6.     pass 
  7.  
  8. def make_smoothies(count): 
  9.     print(f'Making a smoothies with {count} banana slices'
  10.  
  11. pieces = 0 
  12. count = fresh_fruit.get('banana', 0) 
  13. if count >= 2: 
  14.     pieces = slice_bananas(count
  15.  
  16. try: 
  17.     smoothies = make_smoothies(pieces) 
  18. except OutOfBananas: 
  19.     out_of_stock() 

 

還有一種傳統(tǒng)的寫法也很常見,就是把if/else結(jié)構(gòu)上方那條pieces = 0的賦值語句移動到else塊中。

 

  1. count = fresh_fruit.get('banana', 0) 
  2. if count >= 2: 
  3.     pieces = slice_bananas(count
  4. else
  5.     pieces = 0 
  6.  
  7. try: 
  8.     smoothies = make_smoothies(pieces) 
  9. except OutOfBananas: 
  10.     out_of_stock() 

 

這種寫法看上去稍微有點兒怪,因為if與else這兩個分支都給pieces變量定義了初始值。根據(jù)Python的作用域規(guī)則,這種分別定義變量初始值的寫法是成立的。雖說成立,但這樣寫看起來比較別扭,所以很多人喜歡用第一種寫法,也就是在進(jìn)入if/else結(jié)構(gòu)之前,先把pieces的初始值給設(shè)置好。

改用海象操作符來實現(xiàn),可以少寫一行代碼,而且能夠壓低count變量的地位,讓它只出現(xiàn)在if塊里,這樣我們就能更清楚地意識到pieces變量才是整段代碼的重點。

 

  1. pieces = 0 
  2. if (count := fresh_fruit.get('banana', 0)) >= 2: 
  3.     pieces = slice_bananas(count
  4.  
  5. try: 
  6.     smoothies = make_smoothies(pieces) 
  7. except OutOfBananas: 
  8.     out_of_stock() 

 

對于在if與else分支里面分別定義pieces變量的寫法來說,海象操作符也能讓代碼變得清晰,因為這次不用再把count變量放到整個if/else塊的上方了。

 

  1. if (count := fresh_fruit.get('banana', 0)) >= 2: 
  2.     pieces = slice_bananas(count
  3. else
  4.     pieces = 0 
  5.  
  6. try: 
  7.     smoothies = make_smoothies(pieces) 
  8. except OutOfBananas: 
  9.     out_of_stock() 

 

Python新手經(jīng)常會遇到這樣一種困難,就是找不到好辦法來實現(xiàn)switch/case結(jié)構(gòu)。最接近這種結(jié)構(gòu)的做法是在if/else結(jié)構(gòu)里面繼續(xù)嵌套if/else結(jié)構(gòu),或者使用if/elif/else結(jié)構(gòu)。

例如,我們想按照一定的順序自動給客人制作飲品,這樣就不用點餐了。下面這段邏輯先判斷能不能做香蕉冰沙,如果不能,就做蘋果汁,還不行,就做檸檬汁:

 

  1. count = fresh_fruit.get('banana', 0) 
  2. if count >= 2: 
  3.     pieces = slice_bananas(count
  4.     to_enjoy = make_smoothies(pieces) 
  5. else
  6.     count = fresh_fruit.get('apple', 0) 
  7.     if count >= 4: 
  8.         to_enjoy = make_cider(count
  9.     else
  10.         count = fresh_fruit.get('lemon', 0) 
  11.         if count
  12.             to_enjoy = make_lemonade(count
  13.         else
  14.             to_enjoy = 'Nothing' 

 

這種難看的寫法其實在Python代碼里特別常見。幸好現(xiàn)在有了海象操作符,讓我們能夠輕松地模擬出很接近switch/case的方案。

 

  1. if (count := fresh_fruit.get('banana', 0)) >= 2: 
  2.     pieces = slice_bananas(count
  3.     to_enjoy = make_smoothies(pieces) 
  4. elif (count := fresh_fruit.get('apple', 0)) >= 4: 
  5.     to_enjoy = make_cider(count
  6. elif count := fresh_fruit.get('lemon', 0): 
  7.     to_enjoy = make_lemonade(count
  8. else
  9.     to_enjoy = 'Nothing' 

 

這個版本只比原來短五行,但是看起來卻清晰得多,因為嵌套深度與縮進(jìn)層數(shù)都變少了。只要碰到剛才那種難看的結(jié)構(gòu),我們就應(yīng)該考慮能不能改用海象操作符來寫。

Python新手還會遇到一個困難,就是缺少do/while循環(huán)結(jié)構(gòu)。例如,我們要把新來的水果做成果汁并且裝到瓶子里面,直到水果用完為止。下面先用普通的while循環(huán)來實現(xiàn):

 

  1. FRUIT_TO_PICK = [ 
  2.     {'apple': 1, 'banana': 3}, 
  3.     {'lemon': 2, 'lime': 5}, 
  4.     {'orange': 3, 'melon': 2}, 
  5.  
  6. def pick_fruit(): 
  7.     if FRUIT_TO_PICK: 
  8.         return FRUIT_TO_PICK.pop(0) 
  9.     else
  10.         return [] 
  11.  
  12. def make_juice(fruit, count): 
  13.     return [(fruit, count)] 
  14.  
  15. bottles = [] 
  16. fresh_fruit = pick_fruit() 
  17. while fresh_fruit: 
  18.     for fruit, count in fresh_fruit.items(): 
  19.         batch = make_juice(fruit, count
  20.         bottles.extend(batch) 
  21.     fresh_fruit = pick_fruit() 
  22.  
  23. print(bottles) 

 

這種寫法必須把fresh_fruit = pick_fruit()寫兩次,第一次是在進(jìn)入while循環(huán)之前,因為我們要給fresh_fruit設(shè)定初始值,第二次是在while循環(huán)體的末尾,因為我們得把下一輪需要處理的水果列表填充到fresh_fruit里面。

如果想復(fù)用這行代碼,可以考慮loop-and-a-half 模式。這個模式雖然能消除重復(fù),但是會讓while循環(huán)看起來很笨,因為它成了無限循環(huán),程序只能通過break語句跳出這個循環(huán)。

 

  1. FRUIT_TO_PICK = [ 
  2.     {'apple': 1, 'banana': 3}, 
  3.     {'lemon': 2, 'lime': 5}, 
  4.     {'orange': 3, 'melon': 2}, 
  5.  
  6. bottles = [] 
  7. while True:                     # Loop 
  8.     fresh_fruit = pick_fruit() 
  9.     if not fresh_fruit:         # And a half 
  10.         break 
  11.     for fruit, count in fresh_fruit.items(): 
  12.         batch = make_juice(fruit, count
  13.         bottles.extend(batch) 
  14.  
  15. print(bottles) 

 

有了海象操作符,就不需要使用loop-and-a-half模式了,我們可以在每輪循環(huán)的開頭給fresh_fruit變量賦值,并根據(jù)變量的值來決定要不要繼續(xù)循環(huán)。這個寫法簡單易讀,所以應(yīng)該成為首選方案。

 

  1. FRUIT_TO_PICK = [ 
  2.     {'apple': 1, 'banana': 3}, 
  3.     {'lemon': 2, 'lime': 5}, 
  4.     {'orange': 3, 'melon': 2}, 
  5.  
  6. bottles = [] 
  7. while fresh_fruit := pick_fruit(): 
  8.     for fruit, count in fresh_fruit.items(): 
  9.         batch = make_juice(fruit, count
  10.         bottles.extend(batch) 
  11.  
  12. print(bottles) 

 

在其他一些場合,賦值表達(dá)式也能縮減重復(fù)代碼。總之,如果某個表達(dá)式或賦值操作多次出現(xiàn)在一組代碼里面,那就可以考慮用賦值表達(dá)式把這段代碼改得簡單一些。

要點

  • 賦值表達(dá)式通過海象操作符(:=)給變量賦值,并且讓這個值成為這條表達(dá)式的結(jié)果,于是,我們可以利用這項特性來縮減代碼。
  • 如果賦值表達(dá)式是大表達(dá)式里的一部分,就得用一對括號把它括起來。
  • 雖說Python不支持switch/case與do/while結(jié)構(gòu),但可以利用賦值表達(dá)式清晰地模擬出這種邏輯。

 

責(zé)任編輯:華軒 來源: 今日頭條
相關(guān)推薦

2021-10-31 18:59:55

Python操作符用法

2010-07-14 14:55:07

Perl操作符

2009-08-19 17:26:28

C# 操作符

2020-03-03 15:42:33

Python字典合并代碼

2022-07-05 07:47:13

Python海象運(yùn)算符

2021-03-18 22:11:23

Python字符開發(fā)

2010-02-23 11:18:25

Python 操作符

2009-07-21 09:31:00

Scala操作符

2009-09-15 17:16:58

LINQ查詢操作符

2012-02-06 09:13:23

LINQ

2009-09-16 09:09:23

Linq Contai

2010-07-14 14:18:51

Perl操作符

2011-04-08 16:26:14

JavaScript

2010-07-14 14:30:31

Perl操作符

2010-07-19 11:00:24

Perl操作符

2010-01-28 11:16:28

C++操作符

2021-10-09 13:48:11

操作符Python運(yùn)算符

2009-07-22 07:45:00

Scala代碼重復(fù)

2010-01-27 11:00:17

C++操作符

2017-01-03 15:56:20

RxJava操作符Android
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产亚洲精品久久久优势 | 成人老司机 | 福利视频一区二区 | 日韩av网址在线观看 | 欧美日韩精品影院 | 亚洲精品大全 | 国产视频中文字幕 | 精品久久久久久久久久久久 | 欧美中文字幕一区二区三区亚洲 | 日本人和亚洲人zjzjhd | 黄色毛片在线看 | 国产成人精品免费 | 麻豆国产一区二区三区四区 | 欧美日韩在线精品 | 国产剧情一区 | 伊人最新网址 | 三级国产三级在线 | 91精品麻豆日日躁夜夜躁 | 中文字幕1区2区 | 天天操夜夜操 | 亚洲免费在线 | 亚洲一区二区三区免费在线观看 | 久久人人网 | 伊人免费视频二 | 一级网站 | 91精品一区二区 | 亚洲欧美中文日韩在线v日本 | 美女视频一区二区三区 | 国产福利免费视频 | 色综合天天天天做夜夜夜夜做 | 视频一区二区三区四区五区 | 日韩欧美国产精品一区二区三区 | 日韩免| 一级毛片网 | 国产成人一区二区三区久久久 | 国产伦精品一区二区三毛 | 久久亚洲精品国产精品紫薇 | 国产精品不卡视频 | 在线观看国产精品一区二区 | 精品蜜桃一区二区三区 | 国产一区二区三区四区五区加勒比 |