python:for-else和while-else應用

出現場景

今天的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顯得更加簡潔,且不用再設置一個標誌變量。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章