天天看點

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

LeetCode 中 一道題目如下

給定一個僅包含大小寫字母和空格 ' ' 的字元串 s,傳回其最後一個單詞的長度。

如果字元串從左向右滾動顯示,那麼最後一個單詞就是最後出現的單詞。 

如果不存在最後一個單詞,請傳回 0 。 

說明:一個單詞是指僅由字母組成、不包含任何空格字元的 最大子字元串。 

示例:

輸入: "Hello World"

輸出: 5

原題連結:

https://leetcode-cn.com/problems/length-of-last-word

終于刷到一條不看答案就能輕松解出來的題目,更重要的是學習到了幾種删除清單中元素的方法,值得做一下筆記

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法
getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

解題思路

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

先說下我的思路:題目要求給一個字元串s,s僅包含字母和空格字元,要求傳回最後一個單詞的長度,考慮如下幾點  

  1. 如果s是空字元,即s="",此時應該傳回0;  
  2. 如果s隻包含空格字元,即s="    ",此時也應該傳回0;  
  3. 如果s既包含字母也包含空格(或者隻包含字母),可以通過split()函數,用一個空格字元切割,這樣就可以得到一個清單,這個清單隻由連續的字母和空字元組成,然後把清單中的所有空字元删除,最後把清單中的最後一項的長度傳回即可;  

是以現在的問題就轉化為:如何删除一個清單中的特定元素,這裡的話,就是删除清單中的空字元,即""

解決方法

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

方法1: 借助一個臨時清單,把非空元素提取到臨時清單中,然後取出臨時清單最後一項,傳回其長度即可   這是最笨的方法,實際運作時也是最耗時的方法

class Solution(object):    def lengthOfLastWord(self, s):        """        :type s: str        :rtype: int        """        if s.isspace():  # 判斷s是否隻由空格字元組成,如s=="   "            return 0        elif s == "":  # 判斷s是否為空字元串,如s==""            return 0        else:  # 如果s不為空,且不全是由空格組成            temp = s.split(" ")  # 通過split方法,用一個空格字元将字元串s進行切割,可以得到由單詞和空字元串組成的清單,将清單賦給temp            new = []  # 定義一個空清單,作為中間變量            for t in temp:  # 周遊temp,把非空元素提取到new中,最後把new的最後一項的長度傳回即可                if t != "":                    new.append(t)            return len(new[-1])
           

在說方法2之前,說一個錯誤的方法 : 使用for循環,正向周遊清單,删除其中的空字元,如下

s = ["","","a", "a", "a","","",""]for i in range(0,len(s)):    if s[i] == "":        del s[i]print(s)
           

運作上述代碼,會報錯

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

原因是當遇到空字元時,把空字元删掉後,清單長度變小了,但是循環周遊時,還是按照最初的長度周遊,導緻溢出;  

另外這樣寫還存在一個弊端:可能會漏删某些空字元,原因是當删掉前面的空字元後,後面的元素依次向前移動,導緻索引與原先對應的值發生變化,如下

b = ["","","a", "a", "a","","",""]for i in range(0,len(b)):    if i >= len(b):  # 加一個判斷,當i大于清單長度時,跳出循環,避免報錯        break    if b[i] == "":        del b[i]print(b)
           
getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

是以我們在解決這個問題前,不能用for循環來正向周遊清單

方法2:

使用while循環  因為for循環無法達到目的,是以考慮使用while循環,如下

class Solution(object):    def lengthOfLastWord(self, s):        """        :type s: str        :rtype: int        """        if s.isspace():  # 判斷s是否隻由空格字元組成,如s=="   "            return 0        elif s == "":  # 判斷s是否為空字元串,如s==""            return 0        else:  # 如果s不為空,且不全是由空格組成            temp = s.split(" ")  # 通過split方法,用一個空格字元将字元串s進行切割,可以得到由單詞和空字元串組成的清單,将清單賦給temp            i = 0  # 設定初始指針,定為0            while i < len(temp):  # 使用while循環,當指針i的值小于清單temp的長度時,則一直循環                if temp[i] == "":  # 從索引0開始,如果temp[i]為空                    del temp[i]  # 則删除該索引對應的值,也就是删除temp[i]                    i -=1  # 删除之後,由于清單整體長度變小了1位(也就是後面的元素都往前提了一位),是以索引i需要減1,以便下次周遊時不丢掉挨着的元素                i += 1 # 判斷完索引i後,給索引自增1,進行下一輪判斷            return len(temp[-1])  # temp所有元素周遊完成後,就剔除了所有空字元串,取出最後一項的長度傳回即可
           

方法3:

for循環倒序删除空字元串  剛才說了使用for循環時,正向周遊會導緻溢出或者結果出錯,但是從後向前周遊是可以的

class Solution(object):    def lengthOfLastWord(self, s):        """        倒序循環删除空字元串        :type s: str        :rtype: int        """        if s.isspace():  # 判斷s是否隻由空格字元組成,如s=="   "            return 0        elif s == "":  # 判斷s是否為空字元串,如s==""            return 0        else:  # 如果s不為空,且不全是由空格組成            temp = s.split(" ")  # 通過split方法,用一個空格字元将字元串s進行切割,可以得到由單詞和空字元串組成的清單,将清單賦給temp            for i in range(len(temp)-1, -1, -1):  # 倒序循環删除空字元串                if temp[i] == "":                    del temp[i]        return len(temp[-1])
           

方法4:

拷貝原清單,然後周遊拷貝的清單來找出空字元,最後再原清單中删除空字元

class Solution(object):    def lengthOfLastWord_3(self, s):        """        :type s: str        :rtype: int        """        if s.isspace():  # 判斷s是否隻由空格字元組成,如s=="   ",用isspace()函數判斷            return 0        elif s == "":  # 判斷s是否為空字元串,如s==""            return 0        else:  # 如果s不為空,且不全是由空格組成            temp = s.split(" ")  # 通過split方法,用一個空格字元将字元串s進行切割,可以得到由單詞和空字元串組成的清單,将清單賦給temp            for i in temp[:]:   # temp[:]是對原始的temp的一個拷貝,是一個新的list,是以,我們周遊新的list,而删除原始的list中的元素                if i == "":                    temp.remove(i)        return len(temp[-1])
           

這樣了解一下:假如有一個清單s = [1,1,2,3,4,4,3,1],現在要把裡面的1都删掉  

我們先拷貝s,得到一個新清單(注意不能用一個變量直接等于s,如a=s,其實a和s都指向同一個清單,本質還是一個),新清單的元素與原清單完全相同   然後周遊新清單,當遇到某個元素的值為1時,就在原清單中把這個元素删掉(使用清單的remove方法删除),因為remove在删除元素時,隻會删掉遇到的第一個目标元素,是以我們繼續周遊新清單,如果再遇到1,就繼續在原清單中删除

最終周遊完新清單,也就會在原清單中把所有1都删掉了     

上述代碼中的 temp[:] 是拷貝原清單得到新清單的一個方法,也可以通過如下方法複制得到一個新清單

1 >>> new_temp = temp[:]2 >>> new_temp = list(temp)3 >>> new_temp = temp*14 >>> import copy  >>> new_temp = copy.copy(temp)
           

關于原地删除清單中特定元素的方法,參考了如下文章:

https://www.jb51.net/article/169070.htm 

關于拷貝清單,參考了如下文章:

https://www.cnblogs.com/ifantastic/p/3811145.html

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法
getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

喜歡記得來一個

getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法
getresourceasstream方法傳回空_python:删除清單中特定元素的幾種方法

繼續閱讀