簡體   English   中英

Python - 從作為另一個元素的子字符串的字符串列表中刪除任何元素

[英]Python - Remove any element from a list of strings that is a substring of another element

所以從字符串列表開始,如下所示

string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']

我想從列表中刪除作為另一個元素的子字符串的任何元素,例如給出結果......

string_list = ['休息','看了','吐']

我有一些代碼可以實現這一點,但它非常丑陋,而且可能不必要地復雜。 有沒有一種簡單的方法可以在 Python 中做到這一點?

第一個構建塊:子字符串。

您可以使用in來檢查:

>>> 'rest' in 'resting'
True
>>> 'sing' in 'resting'
False

接下來,我們將選擇創建新列表的簡單方法。 我們將一項一項地添加到新列表中,檢查它們是否是子字符串。

def substringSieve(string_list):
    out = []
    for s in string_list:
        if not any([s in r for r in string_list if s != r]):
            out.append(s)
    return out

您可以通過排序來減少比較次數來加快速度(畢竟,較長的字符串永遠不能是較短/等長字符串的子字符串):

def substringSieve(string_list):
    string_list.sort(key=lambda s: len(s), reverse=True)
    out = []
    for s in string_list:
        if not any([s in o for o in out]):
            out.append(s)
    return out

這是一個可能的解決方案:

string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']
def string_set(string_list):
    return set(i for i in string_list 
               if not any(i in s for s in string_list if i != s))

print(string_set(string_list))

打印出來:

set(['looked', 'resting', 'spit'])

注意我創建了一個集合(使用生成器表達式)來刪除可能重復的單詞,因為看起來順序無關緊要。

另一個班輪:

[string for string in string_list if len(filter(lambda x: string in x,string_list)) == 1]

應該是相當可讀的,只是不是pythonic。

這是一種方法:

def find_unique(original):
    output = []

    for a in original:
        for b in original:
            if a == b:
                continue     # So we don't compare a string against itself
            elif a in b:
                break
        else:
            output.append(a) # Executed only if "break" is never hit

    return output

if __name__ == '__main__':
    original = ['rest', 'resting', 'look', 'looked', 'it', 'split']
    print find_unique(original)

它利用了這樣一個事實,即我們可以使用in運算符輕松檢查一個字符串是否是另一個字符串的子字符串。 它基本上遍歷每個字符串,檢查它是否是另一個字符串的子字符串,如果不是,則將自身附加到輸出列表中。

這會打印出['resting', 'looked', 'split']

這是一個單線,可以滿足您的需求:

filter(lambda x: [x for i in string_list if x in i and x != i] == [], string_list)

例子:

>>> string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']
>>> filter(lambda x: [x for i in string_list if x in i and x != i] == [], string_list)
['resting', 'looked', 'spit']

這是一種非最佳方式,僅當列表很小時才使用:

for str1 in string_list:
    for str2 in string_list:
        if str1 in str2 and str1 != str2:
            string_list.remove(str1)

這是執行此操作的有效方法(相對於上述解決方案 ;) ),因為這種方法大大減少了列表元素之間的比較次數。 如果我有一個很大的列表,我肯定會選擇這個,當然你可以把這個解決方案變成一個 lambda 函數,讓它看起來很小:

string_list = ['rest', 'resting', 'look', 'looked', 'it', 'spit']
for item in string_list: 
  for item1 in string_list:
    if item in item1 and item!= item1:
      string_list.remove(item)

print string_list

輸出:

>>>['resting', 'looked', 'spit']

希望能幫助到你 !

這是另一種方法。 假設您有一個排序列表開始,並且您不必就地進行篩選,我們可以一次選擇最長的字符串:

string_list = sorted(string_list)
sieved = []
for i in range(len(string_list) - 1):
    if string_list[i] not in string_list[i+1]:
        sieved.append(string_list[i])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM