2017-09-21 2 views
1

미리 도움을 주셔서 감사합니다.어떻게 파이썬에서 부분 문자열을 재귀 적으로 검색합니까?

나는 문자열

내가 목록의 모든 요소에 각 요소의 퍼센트 일치 할 필요가
full_name_list = ["hello all","cat for all","dog for all","cat dog","hello cat","cat hello"] 

의 목록을 가지고있다. 예를 들어, 먼저 "hello all"["hello", "all"]으로 분해해야하며 "hello""hello cat"에 있으며 따라서 50 % 일치합니다. 각 하위 목록의 첫 번째 단어는 문자열 것을 포함하는 요소 다음에 검색되는 문자열을 포함 볼 수 있듯이 여기

hello all [u'hello', u'hello all', u'hello cat', u'cat hello'] [u'all', u'hello all', u'cat for all', u'dog for all'] 
    cat for all [u'cat', u'cat for all', u'cat dog', u'hello cat', u'cat hello'] [u'for', u'cat for all', u'dog for all'] [u'all', u'hello all', u'cat for all', u'dog for all'] 
    dog for all [u'dog', u'dog for all', u'cat dog'] [u'for', u'cat for all', u'dog for all'] [u'all', u'hello all', u'cat for all', u'dog for all'] 
    cat dog  [u'cat', u'cat for all', u'cat dog', u'hello cat', u'cat hello'] [u'dog', u'dog for all', u'cat dog']  
    hello cat [u'hello', u'hello all', u'hello cat', u'cat hello'] [u'cat', u'cat for all', u'cat dog', u'hello cat', u'cat hello']  
    cat hello [u'cat', u'cat for all', u'cat dog', u'hello cat', u'cat hello'] [u'hello', u'hello all', u'hello cat', u'cat hello']  

, 내가 지금까지있는 것입니다. 한 단어 일치에 대해이 작업을 수행 할 수 있으며 개별 단어를 교차하여 간단하게 일치 항목을 가져 와서이 과정을 계속할 수 있음을 깨달았습니다.

cat for all [(cat,for) [u'cat for all']] [(for,all) [u'cat for all', u'dog for all']] 

문제점 가장 긴 문자열의 길이를 알 수 없으므로이 문제는 재귀 적으로 발생합니다. 또한이 문자열 검색을 수행하는 더 좋은 방법이 있습니까? 궁극적으로 현실적으로 일치하는 문자열을 찾으려고합니다. "hello cat" == "cat hello". 나는 또한 50 % 일치를 찾고 싶다.

내가받은 아이디어는 이진 트리를 사용하는 것이지만 어떻게 파이썬으로이 작업을 수행 할 수 있습니까? 여기 내 코드는 내가 프로그래머 아닙니다, 지금까지 내가이 저와 너무 베어 그렇게 좋아 보이지 않습니다 알고

logical_list = [] 
logical_list_2 = [] 
logical_list_3 = [] 
logical_list_4 = [] 
match_1 = [] 
match_2 = [] 
i = 0 

logical_name_full = logical_df['Logical'].tolist() 
for x in logical_name_full: 
    logical_sublist = [x]+x.split() 
    logical_list.append(logical_sublist) 



for sublist in logical_list: 
    logical_list_2.append(sublist[0]) 
    for split_words in sublist[1:]: 
     match_1.append(split_words) 
     for logical_names in logical_name_full: 
      if split_words in logical_names: 
       match_1.append(logical_names) 
     logical_list_2.append(match_1) 
     match_1 = [] 
    logical_list_3.append(logical_list_2) 
    logical_list_2 = [] 

답변

0

내가 문제를 올바르게 이해 해요, 당신은 문자열 목록이 있고, 당신은 문자열의 단어의 % 일치를 찾고 싶습니다. 비율은 단어의 총 수에서 문자열의 단어 수에 의해 결정됩니다. 그렇다면,이 코드 예제는 충분합니다 :

for i in full_name_list: 
    if word in i.split(" "): 
     total_words = len(i.split(" ")) 
     match_words = 0 
     for w in i.split(" "): 
      if word == w: 
       match_words += 1 
     print(i + " Word match: " + str((match_words/total_words)*100) + "%") 

일치하는 문자열에서 단어의 순서가 중요하지 않은 경우, 여러 단어 문자열을 일치하는 경우 : = "테스트 문자열" full_name_list = [ "테스트 뭔가 단어 ","테스트 문자열 뭔가 ","테스트 문자열 ","문자열 테스트 ","문자열 뭔가 시험 "] 결과 = []

for i in full_name_list: 
    if len([item for item in word if item in i]) > 0: 
     total_words = len(i.split(" ")) 
     match_words = 0.0 
     for single_word in word.split(" "): 
      for w in i.split(" "): 
       if single_word == w: 
        match_words += 1 
     results.append(i + "," + str((match_words/total_words)*100) + "%") 

with open("file.csv", "w") as f: 
    for i in results: 
     f.write(i+"\n") 
+0

이 멋지다, 난 그냥 모두의 시각화를 볼 수 있도록 엑셀 인쇄 다음이 모두 밖으로 변수 "단어"대신에 내 목록의 각 단어를 사용하는 방법을 알아낼 필요 퍼센트 일치. 전체 단어의 각 구성 요소를 하나씩 다른 단어로 매칭하는 대신, 전체 단어가 다른 전체 단어와 어떻게 관련되어 있는지를 볼 수 있기 때문에 아이디어에 대한 다른 시각을 주셔서 감사합니다. –

+0

@EdwardMordechay 배열을 가져와 변수 variable에 .join ("") 넣을 수 있습니다. –

+0

@EdwardMordechay 그리고 시각화를 위해 Excel을 사용하면 CSV를 사용할 수 있습니다. 이 경우 결과 파일은 results.append (i + ","+ str (match_words/total_words) * 100) + "%")로 표시됩니다. 이후 파일 IO가 필요합니다. –

0
내가 (그렇지 않으면 당신이 요구하는지 알고 있다고 생각

, 그냥 내 대답에 대한 논평, 내가 도우려고 노력할 것입니다).

full_name_list = ["hello all","cat for all","dog for all","cat dog","hello cat","cat hello"] 

for i in range(len(full_name_list)): 
    full_name_list[i] = full_name_list[i].split(' ') 

def match(i, j): 
    word = full_name_list[i][j] 

    for fullname in full_name_list: 
     if full_name_list.index(fullname) == i: continue 

     for name in fullname: 
      if word == name: 
       fullname_str = fullname[0] 

       for i in range(1,len(fullname)): 
        fullname_str += ' ' + fullname[i] 

       return '"{}" is a {}% match to "{}"'.format(name, int(100/len(fullname)), fullname_str) 

print(match(0,1)) 

사용자 입력 두 개의 매개 변수 목록에있는 이름의 인덱스에 대한 i, 그리고 전체 이름에있는 이름의 인덱스에 대한 j : 나는 당신이 요구하는지 무슨 생각을 않는 작은 프로그램을 작성 . 그런 다음 함수가 이름과 일치하는 문자열과 일치하는 문자열을 반환합니다. 또한 단어 자체와 일치하는 것을 방지합니다. 나는 그 기능을 바닥에서 한 번 실행했다. 과 같이 all이라는 단어를 찾아 성공합니다.

다시 한번 대답 해 주시겠습니까? 찾은 첫 번째 일치 항목 만 반환하지만 모든 항목을 반환하도록 쉽게 수정할 수 있습니다.

+0

이것은 정확히 필요한 부분이지만, 몇 가지 추가 부품이 필요합니다. 1. 퍼센트 일치를 얻기 위해 full_name_list의 각 구성 요소를 사용해야합니다. 2. 문자열에 여러 단어가 있으면 개별 단어를 찾아야합니다 일치 및 여러 단어 일치 (예 : 예제에서 "all"을 검색하지만 "hello"와 "hello all"을 검색해야합니다. 3. 적어도 하나의 일치 항목이있는 모든 단어가 반환되어야합니다. –

0

나는 당신이 요구 한 변경을했다. 아시다시피, 나는 here에서 가져온 서브셋 함수를 사용했으며 itertools (이는 파이썬으로 내장되어 있음)에서 가져옵니다. 이것이 문제가되면 알려주십시오.

다음은 새로운 코드입니다. 나는 당신이 행동에서의 모습을 볼 수 있도록 바닥에서 그것을 돌렸다. i 색인을 matches 함수에 입력하십시오. ifull_name_list에있는 이름의 색인입니다. 나는 그것이 당신이 요구 한 전부라고 믿습니다.

from itertools import chain, combinations 

full_name_list = ["hello all","cat for all","dog for all","cat dog","hello cat","cat hello"] 

for i in range(len(full_name_list)): 
    full_name_list[i] = full_name_list[i].split(' ') 

def powerset(iterable): 
    s = list(iterable) 
    return list(chain.from_iterable(combinations(s, r) for r in range(1, len(s)+1))) 


def subset(string, container): 
    if string not in powerset(container): return False 

    return True 

def makestring(names): 
    fullname_str = names[0] 

    for i in range(1,len(names)): 
     fullname_str += ' ' + names[i] 

    return fullname_str 

def matches(i): 
    results = [] 

    fullname = full_name_list[i] 
    fullnamePS = powerset(fullname) 

    for fullname in full_name_list: 
     if full_name_list.index(fullname) == i: continue 

     for names in fullnamePS: 
      if subset(names, fullname): 

       results.append((int(100 * len(names)/len(fullname)), makestring(names), makestring(fullname))) 

    return results 

for result in matches(1): 
    print('"{}" is a {}% match to "{}"'.format(result[1],result[0],result[2])) 
관련 문제