为了账号安全,请及时绑定邮箱和手机立即绑定

从列表中删除数字,如果不包含在其他列表的子字符串中

从列表中删除数字,如果不包含在其他列表的子字符串中

一只萌萌小番薯 2021-08-05 16:11:04
这是我的情况:我有一个产品名称列表,例如:BLUEAPPLE, GREENBUTTON20, 400100DUCK20(len = 9000)和一个官方项目名称列表,例如:BLUEAPPLE, GREENBUTTON, 100DUCK。(len = 2700)由于我将模糊字符串匹配应用于产品 - 项目,我想从产品名称中去除不必要的数字 - 但保留在官方项目名称中表示的数字。我想出了一个解决方案,但问题是它的工作速度非常慢。def remove_nums(product):    if bool(re.search('\d'), product):        for item in item_nums_list:            if item in product_name:                substrings = [u for x in product_name.split(item) for u in (x, item)][:-1]                no_num_list = [re.sub('(\d+)', '', substring) if substring not in item else substring for substring in substrings]                return ''.join(no_num_list)        return re.sub('(\d+)', '', product)    else:        return product例子:product_name = '400100DUCK20'item = '100DUCK'substrings = ['400','100DUCK','20']no_num_list = ['','100OG','']returns '100DUCK'这个函数被映射,以便它循环遍历产品列表中的每个产品。我一直在想办法在这里使用 lambdas、maps、applys 等,但我无法完全理解它。使用直接列表或熊猫完成我想要做的事情的最有效方法是什么?或者,我从 postgres 数据库中获取这些项目和产品列表,所以如果您认为在 psql 中这样做会更快,我会走这条路。
查看完整描述

2 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

difflib.get_close_matches() 至少会帮助清理您的代码,并且可能会运行得更快。


import difflib

p_names = ['BLUEAPPLE', 'GREENBUTTON20', '400100DUCK20']

i_names = ['BLUEAPPLE', 'GREENBUTTON', '100DUCK']

for p in p_names:

    print(difflib.get_close_matches(p, i_names))


>>> 

['BLUEAPPLE']

['GREENBUTTON']

['100DUCK']

>>> 

仍然会进行很多比较,它必须将 p_names 中的每个字符串与 i_names 中的每个字符串匹配。


类似于您使用正则表达式查找匹配项的方法:


import re

for p in p_names:

    for i in i_names:

        if re.search(i, p):

            print(i)

            # stop looking

            break


查看完整回答
反对 回复 2021-08-05
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

试试这个:


def remove_nums(product):

    if re.search('\d', product):

        for item in item_nums_list:

            if item in product:

                return item

        return re.sub('(\d+)', '', product)

else:

    return product

另外,请确保您使用的是普通的 python 解释器。IPython 和其他具有调试功能的解释器比常规解释器慢很多。


不过,您可能要考虑先进行一些设置操作。这是一个小例子:


product_set = set(product_list)

item_number_set = set(item_number_list)


# these are the ones that match straight away

product_matches = product_set & item_number_set


# now we can search through the substrings of ones that don't match

non_matches = product_set - item_number_set

for product in non_matches:

    for item_number in item_number_set:

        if item_number in product:

            product_matches.add(product)

            break


# product_matches is now a set of all unique codes contained in both lists by "fuzzy match"

print(product_matches)

您可能会丢失它们出现的顺序,但也许您可以找到一种方法来修改它以供您使用。


查看完整回答
反对 回复 2021-08-05
  • 2 回答
  • 0 关注
  • 138 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信