1. 程式人生 > >用一個Python程式來判斷一個字串是否是另一個字串的sublist

用一個Python程式來判斷一個字串是否是另一個字串的sublist

刷題時遇到這樣一道題目,剛開始沒有什麼頭緒,後來參考了給出的答案:

def is_sublist(l,s):
    sub_set=False
    if s==[]:
        sub_set=True
    elif s==l:
        sub_set=True
    elif len(s)>len(l):
        sub_set=False
    else:
        for i in range(len(l)):
            if l[i]==s[0]:
                n=1
                while(n<len(s))and (l[i+n]==s[n]):
                    n+=1
                if n==len(s):
                    sub_set=True
    return sub_set
print(is_sublist([1,2,3,4,7],[2,4]))

顯然,答案考慮很全面,如果s==[]或者s==l,那麼為True,如果len(s)>len(l),那麼為False,可見寫程式時要先把最簡單的情況列出來,然後在else中,依次將l的每個元素與s[0]比較,如果相等,說明有可能為True,取n來作為l中與s相等的元素的個數,如果n<len(s)並且l[n+i]==s[n],此時滿足,n+=1,如果迴圈完成n==len(s),返回True,最後對於其他情況,都是返回False。

理解了答案的思路之後,再自己下手寫一遍:

def is_sublist(l,s):
    sub_set=False
    if s==[]:
        sub_set=True
    elif s==l:
        sub_set=True
    elif len(s)>len(l):
        sub_set=False
    else:
        for i in range(len(l)):
            if l[i]==s[0]:
                n=1
                while (l[i+n]==s[n])and (n<len(s)):
                    n+=1
                    break
                if n==len(s):
                    sub_set=True
    return sub_set
print(is_sublist(['a','b','c','d','e'],['e','d']))

看上去兩個程式沒有什麼區別,然而,這時報錯了。錯誤原因是:list index out of range.,並且指向了while語句。可是和上面對比,除了and前後兩個條件的順序不同之外,沒有什麼其他不一樣,就很奇怪然後去查了Python中and的用法,有人做過筆記說明Python中的and語句是從左向右執行,如果所有條件都滿足,返回最後一個條件,or語句是隻要滿足該條件就返回。所以這個地方的錯誤原因是當and語句前後順序交換後就會先執行左邊的條件,在這裡,n=len(s)-1滿足while之後的條件,n+1即n=len(s),while迴圈繼續進行,這時就出現了問題,s[len(s)]不存在

,即超出了範圍,因此會報錯。而對於第一種寫法,當n=len(s)-1後n+1=len(s),對於and語句的左邊第一個條件就不滿足,就不會執行第二個條件了

說到範圍問題,我的某位大神同學又發現了之前第一個程式中的一個問題,如果s的第一個元素正好是l的最後一個元素並且len(s)>1,根據程式這時n=1,那麼在下面的while語句之後滿足n<len(s),但是l[n+i]就成了l[len(l)],同樣是出範圍。即:

def is_sublist(l,s):
    sub_set=False
    if s==[]:
        sub_set=True
    elif s==l:
        sub_set=True
    elif len(s)>len(l):
        sub_set=False
    else:
        for i in range(len(l)):
            if l[i]==s[0]:
                n=1
                while (l[i+n]==s[n])and (n<len(s)):
                    n+=1
                    break
                if n==len(s):
                    sub_set=True
    return sub_set
print(is_sublist(['a','b','c','d','e'],['e','d']))

顯然這個會報錯並且錯誤原因與第二個程式一樣。看來答案也沒有考慮到這一點。於是再次改進,既然如此,那麼只要是s的第一個元素等於l的最後一個元素並且len(s)>1,就要返回False。以下是我新寫的程式:

def is_sublist(l,s):
    if s==[]:
        return True
    elif s==l:
        return True
    elif len(s)>len(l):
        return False
    else:
        for i in range(len(l)):
            if l[i]==s[0]:
                if i==len(l)-1 and len(s)>1:
                    return False
                else:
                    n=1
                    while (l[n+i]==s[n])and(n<len(s)):
                        n+=1
                        if n==len(s):
                            return True
    return False
print(is_sublist([1,2,3,4,5],[2,3,4]))
print(is_sublist([1,2,3,4,4],[4,1]))
print(is_sublist([1,2,3,4,5],[2,1]))
執行後顯示了正確結果。以上是通過這個問題進一步瞭解了Python中and的用法和list的索引範圍問題,如有不足,還請大家指教~