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