簡體   English   中英

匹配子字符串和字符串列表,如果匹配則返回子字符串

[英]Match list of substrings and strings and return substring if it matches

我見過關於這個話題的疑問,但大多數與我相反。 我有一個字符串列表(一個數據幀的列)和一個子字符串列表。 我想將每個字符串與子字符串列表進行比較如果它包含一個子字符串,則返回該子字符串,否則打印“不匹配”。

    subs = [cat, dog, mouse]

    df

      Name       Number     SubMatch
     dogfood      1           dog
     catfood      3           cat
     dogfood      2           dog
     mousehouse   1           mouse
     birdseed     1           no match

我目前的輸出看起來像這樣:

     Name       Number     SubMatch
     dogfood      1           dog
     catfood      3           dog
     dogfood      2           dog
     mousehouse   1           dog
     birdseed     1           dog

我懷疑我的代碼只是返回該系列中的第一件事,如何將其更改為該系列中的正確內容? 這是功能:

    def matchy(col, subs):
        for name in col:
            for s in subs:
                if any(s in name for s in subs):
                    return s
                else:
                    return 'No Match'

解決這個問題的一般方法是根本不使用循環。 您可以使用str.extract完成此str.extract

p = '({})'.format('|'.join(subs))
df['SubMatch'] = df.Name.str.extract(p, expand=False).fillna('no match')

df

         Name  Number  SubMatch
0     dogfood       1       dog
1     catfood       3       cat
2     dogfood       2       dog
3  mousehouse       1     mouse
4    birdseed       1  no match

這個怎么樣:

def matchy(col, subs):
    for name in col:
        try:
            return next(x for x in subs if x in name)
        except StopIteration:
            return 'No Match'

代碼的問題在於,您正在檢查是否與any對象匹配,但首先返回迭代的第一項( dog )。


編輯榮譽@Coldspeed

def matchy(col, subs):
    for name in col:
        return next(x for x in subs if x in name, 'No match')

我認為您是通過嵌套循環然后再進行內部any測試來使事情復雜化。 這樣做會更好嗎:

def matchy(col, subs):
        for name in col:
            for s in subs:
                if s in name:
                    return s
                else:
                    return 'No Match'

除非有缺少代碼的代碼,否則您的代碼似乎會返回第一次比較的結果,而實際上不會查看col列表中的任何其他項目。 如果您寧願堅持使用嵌套循環,建議您像這樣修改代碼:

def matchy(col, subs):
    subMatch = []
    for name in col:
        subMatch.append('No Match')
        for s in subs:
            if s in name:
                subMatch[-1] = s
                break
    return subMatch

假定col是包含列信息(dogfood,mousehouse等)的字符串的列表,並且subs是包含要搜索的子字符串的字符串的列表。 subMatch是返回字符串列表matchy包含在每個商品的搜索結果col

對於我們檢查的col每個值,我們將'No Match'字符串附加到subMatch,基本上假設我們沒有找到匹配項。 然后我們遍歷subs ,檢查子串s是否包含在name 如果存在匹配項,則subMatch[-1] = s用匹配的子字符串替換我們附加的最新'No Match' ,然后由於無需搜索任何內容,因此我們跳到col的下一項更多的價值。 請注意, subMatch[-1] = s可以用其他方法代替,例如先執行subMatch.pop()然后再執行subMatch.append(s) ,盡管在這一點上我認為這是更個人的偏愛。 檢查col所有元素后,將返回subMatch ,此時您可以根據需要進行處理。

暫無
暫無

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

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