Python 匹配子字符串和字符串的列表,如果匹配,则返回子字符串
我见过很多关于这个话题的问题,但大多数都与我的相反。我有一个字符串列表(数据帧的列)和一个子字符串列表。我想将每个字符串与子字符串列表进行比较,如果它包含子字符串,则返回该子字符串,否则打印“不匹配”Python 匹配子字符串和字符串的列表,如果匹配,则返回子字符串,python,string,pandas,Python,String,Pandas,我见过很多关于这个话题的问题,但大多数都与我的相反。我有一个字符串列表(数据帧的列)和一个子字符串列表。我想将每个字符串与子字符串列表进行比较,如果它包含子字符串,则返回该子字符串,否则打印“不匹配” subs = [cat, dog, mouse] df Name Number SubMatch dogfood 1 dog catfood 3 cat d
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
,就可以完成这项工作:
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
解决这个问题的泛泛方法是根本不使用循环。您只需使用
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
)
编辑kudos@Coldspeed
def matchy(col, subs):
for name in col:
return next(x for x in subs if x in name, '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
)
编辑kudos@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'
我认为嵌套循环会使事情变得过于复杂,而
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
,尽管在这一点上我认为这更符合个人偏好。检查完列
中的所有元素后,将返回子匹配
,此时您可以随意处理它。除非缺少解释它的代码,否则代码将返回第一次比较的结果,实际上不查看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
,尽管在这一点上我认为这更符合个人偏好。检查完col
中的所有元素后,将返回subMatch
,此时您可以随意处理它。您不需要any(s in name for s in subs)
在第4行循环,因为您已经在第3行的subs列表上循环了。您不需要any(s in name for s in subs)
在第4行中循环,因为您已经在第3行中循环了SUB列表。有一个默认参数,如果没有其他参数,则返回该参数。您可以去掉try except
并将其简化为一行-下一行((x代表subs中的x,如果x代表name),“不匹配”)
@cᴏʟᴅsᴘᴇᴇᴅ 谢谢你的提示!我不知道。@cᴏʟᴅsᴘᴇᴇᴅ 一个人不应该在这里使用产生?有一个默认参数,如果没有其他参数,则返回该参数。您可以去掉try except
并将其简化为一行-下一行((x代表subs中的x,如果x代表name),“不匹配”)
@cᴏʟᴅsᴘᴇᴇᴅ 谢谢你的提示!我不知道。@cᴏʟᴅsᴘᴇᴇᴅ 这里的yield
不是吗?@Vaishalip
是一种正则表达式模式;-)(”(猫、狗、老鼠)
)这是前几名中唯一有效的答案。谢谢@Vaishalip
是一种正则表达式模式;-)(”(猫|狗|鼠)
)这是前几名中唯一有效的答案