Replace strings based on similarity

拥有回忆 提交于 2020-01-05 04:21:12

问题


I am trying to replace strings in one list with strings in another list.

strlist = ['D-astroid 3-cyclone', 'DL-astroid 3-cyclone', 'DL-astroid', 'D-comment', 'satellite']
to_match = ['astroid 3-cyclone', 'D-comment', 'D-astroid']

Expected Output:

str_list = ['astroid 3-cyclone', 'astroid 3-cyclone', 'D-astroid', 'D-comment', 'satellite']

and also output a dictionary containing the mappings

dict = 
{'astroid 3-cyclone':['astroid 3-cyclone', 'astroid 3-cyclone'],
'D-comment':'D-comment',
'D-astroid':'DL-astroid',
}

I am trying to implement it in the following way for a test case using difflib,

from difflib import SequenceMatcher
from pprint import pprint


def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()


strlist = ['D-astroid 3-cyclone', 'DL-astroid 3-cyclone', 'DL-astroid', 'D-comment']
to_match = ['astroid 3-cyclone', 'D-comment', 'D-astroid']
similarity = similar('DL-astroid', 'astroid 3-cyclone')
pprint(similarity)

Basically, if there is a similarity match of above 0.9 or 0.85, the string in strlist has to be replaced with string in to_match list. Could use two for loops to check whether an item in strlist has high similarity ratio (>0.9) with item in to_match. I'm not sure if this is an efficient way to implement.

Any suggestions?

EDIT: My try, I am not sure how to create the dictionary though.

from difflib import SequenceMatcher
from pprint import pprint
def similar(a, to_match):
    percent_similarity = [SequenceMatcher(None, a, b).ratio() for b in to_match]
    max_value_index = [i for i, j in enumerate(percent_similarity) if j == max(percent_similarity)][0]
    map = [to_match[max_value_index] if max(percent_similarity) > 0.9 else a][0]
    return map


strlist = ['D-saturn 6-pluto', 'D-astroid 3-cyclone', 'DL-astroid 3-cyclone', 'DL-astroid', 'D-comment', 'literal']
to_match = ['saturn 6-pluto', 'pluto', 'astroid 3-cyclone', 'D-comment', 'D-astroid']

map = [similar(item, to_match) for item in strlist]
pprint(map)

回答1:


You can make dictionary from the second list and apply it to the first:

strlist = ['D-astroid 3-cyclone', 'DL-astroid 3-cyclone', 'DL-astroid', 'D-comment', 'satellite']
to_match = ['astroid 3-cyclone', 'D-comment', 'D-astroid']
d1 = {i.split('-')[-1]:i for i in to_match}
result1 = [d1.get(i.split('-')[-1], i) for i in strlist]
result2 = {b:[i for i in strlist if i.endswith(a)] for a, b in d1.items()}
result2 = {a:b if len(b) != 1 else b[0] for a, b in result2.items()}

Output:

['astroid 3-cyclone', 'astroid 3-cyclone', 'D-astroid', 'D-comment', 'satellite']
{'astroid 3-cyclone': ['D-astroid 3-cyclone', 'DL-astroid 3-cyclone'], 'D-comment': 'D-comment', 'D-astroid': 'DL-astroid'}


来源:https://stackoverflow.com/questions/57296078/replace-strings-based-on-similarity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!