猿问

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

这是我的情况:


我有一个产品名称列表,例如:

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 中这样做会更快,我会走这条路。


一只萌萌小番薯
浏览 194回答 2
2回答

心有法竹

difflib.get_close_matches() 至少会帮助清理您的代码,并且可能会运行得更快。import difflibp_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 refor p in p_names:    for i in i_names:        if re.search(i, p):            print(i)            # stop looking            break

白衣染霜花

试试这个: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 awayproduct_matches = product_set & item_number_set# now we can search through the substrings of ones that don't matchnon_matches = product_set - item_number_setfor 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)您可能会丢失它们出现的顺序,但也许您可以找到一种方法来修改它以供您使用。
随时随地看视频慕课网APP

相关分类

Python
我要回答