[英]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.