出現場景
今天的leetcode每日一題中遇到這種寫法,第一次用到,感覺很神奇,省去了很多不必要的步驟。
題目:1160. 拼寫單詞
給你一份『詞彙表』(字符串數組) words 和一張『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼寫出 words 中的某個『單詞』(字符串),那麼我們就認爲你掌握了這個單詞。
注意:每次拼寫時,chars 中的每個字母都只能用一次。
返回詞彙表 words 中你掌握的所有單詞的長度之和。
輸入:words = [“cat”,“bt”,“hat”,“tree”], chars = “atach”
輸出:6
解釋:
可以形成字符串 “cat” 和 “hat”,所以答案是 3 + 3 = 6。
方法:hashmap進行字符數量比對,如果chars中的字符數量大於等於words中每個單詞的字符數量,則表明該單詞學會了。
class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
ans = 0
hashmap = {}
for c in chars:
hashmap[c] = 1 if c not in hashmap else hashmap[c] + 1
for word in words:
hashmap2 = {}
for w in word:
hashmap2[w] = 1 if w not in hashmap2 else hashmap2[w] + 1
for k, v in hashmap2.items():
if k not in hashmap or v > hashmap[k]:
break
else: # 這裏就是for-else
ans += len(word)
return ans
for-else
可以看到上面代碼中的else是與for對齊,查閱相關資料介紹,Python是有這種寫法,在Python 中,else 除了能與 if 配合外,還能和 for、while 配對使用。
官方說明:
Python循環語句(for, while)有可能帶一個else分支,當一個for循環正常執行完畢時或者當一個while循環正常執行完畢(循環條件變爲false)時它被觸發執行,但是如果這個循環被break語句非正常中止時,則這個else分支不執行。
上面的代碼正好需要這種需求,每個字符數量比較完畢後才決定是否更新ans,如果中途不滿足就break,ans也不會被更新。
這裏以while-else爲例:
- 無break時候
i = 0
while i < 7:
print(i)
i += 1
else:
print('no interrupt')
結果:
0
1
2
3
4
5
6
no interrupt
- 有break的時候
i = 0
while i < 7:
print(i)
i += 1
if i == 3:
break
else:
print('no interrupt')
結果:
0
1
2
從上面兩個對比中可以看到,如果break得到執行時,else操作不會得到執行。
這樣的寫法的好處在於可以減少狀態flag來表示循環結果是如何,之前的寫法是對循環結果用一個標誌變量表示,最終依據標誌變量來看是否執行else下的操作:
flag = 0
i = 0
while i < 7:
print(i)
i += 1
if i == 3:
flag = 1
break
if flag:
print("has interrupt")
else:
print("has no interrupt")
比較繁瑣,代碼不夠簡潔。使用while-else顯得更加簡潔,且不用再設置一個標誌變量。