개인 자료란 (JE)

  서버 커뮤니티

Profile logdev 대표칭호 없음
Profile

python

파이썬으로 검색 알고리즘 짜기

2020.05.31 조회 수 141 추천 수 1

대기업의 유명한 인터넷 메인을 보면 

큰 검색창이 서 있는 것을 볼 수 있다.


하지만 검색 시스템은 어떻게 만들까?


그 고민에서 문제를 풀어나가보자


일단 무엇이든 검색할 데이터가 필요할 것이다


그리고 그 데이터 중에 검색한 내용에 대한 체크가 필요할 것이다.


그럼 본격적으로 만들어 보자


먼저 우리는 검색 체크 기능만 만들어 보자


def search(valuelist: list, inputlist: list):
    finallist = []
    return finallist

일단 이렇게 함수를 만들어준다

valuelist 는 검색할 데이터의 리스트이다

inputlist 는 검색한 값이다

우린 valuelist = ["개발", "깃허브"]

그리고 입력 값은 inputlist = ["개"] 라고 가정하겠다

그리고 마지막에 검색에 일치하는 모든 값을 넣는 곳이 finallist라고 하자

(원래 어떤 글자가 검색에 일치했는지 여부를 알기 위해 2차원 배열이나 리스트 두개로 뽑아내는 것도 가능하나 오늘은 검색의 핵심 기능만 만든다.)


먼저 모든 valuelist 에 있는 값을 가져오는게 가능해야 하기 때문에 for 문으로 모든 값을 빼내오는 작업을 한다.


def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        pass
    return finallist

이렇게 작성하면 우리는 valuelist[valueindex] 로 valuelist 의 특정 인덱스의 값을 가져올 수 있다.


우리는 한 글자씩 어떤 글자와 일치하는지 검사해야 하기 때문에

valuelist[valueindex] 의 값을 리스트화 시켜서 변수에 넣어준다


def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
    return finallist

이렇게 작성하면 thisvalue 안에 ["개", "발"] 과 다음 값으로 ["깃", "허", "브"] 가 들어가게 된다

그럼 이제 inputlist 의 한글자씩 일치하는지 검사해야 하기 때문에 for 문으로 한 글자씩 뽑아낸다


def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        for inputindex in range(0, len(inputlist)):
            pass
    return finallist

그리고 나온 값을 사용하기 편하게 변수에 담는다.


def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
    return finallist

그러면 thisinput에는 "개", "발" 이 각각 담긴다.

이제 또다시 for 문으로 일치하는지 여부를 검사한다.


def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
            for check in range(0, len(thisvalue)):
                if thisvalue[check] == thisinput:
                    pass
    return finallist

그럼 이제 몇 글자 일치하는지에 대한 여부를 가져와야 하기 때문에 correct 라는 변수를 생성해 맞을 때마다 1을 더한다

def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        correct = 0
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
            for check in range(0, len(thisvalue)):
                if thisvalue[check] == thisinput:
                    correct += 1
    return finallist

이렇게 작성하면 correct 로 얼마나 일치하는지에 대한 여부를 가져올 수 있다.

하지만  한 글자라도 일치하면 다시 검사할 필요가 있을까?

이해가 안되는 분들을 위해 가정으로 왜 이 코드가 오류를 일으킬 수 있는지 설명하죠.


valuelist = ["개개발", "코코딩"] 

inputlist = ["개"]라고 할때

아마 마지막으로 작성한 check 변수 for 문에서는 

'개'라는 값을 가지고 두번 검사할 것이다.

분명 한 글자만 일치하지만 두번 검사되는 대참사가 발생하게 된다.

이를 방지하기 위해 우린 일치하면 break 로 for 문을 빠져나와야 한다.

def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        correct = 0
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
            for check in range(0, len(thisvalue)):
                if thisvalue[check] == thisinput:
                    correct += 1
                    break
    return finallist

그럼 완료 되었을까? 아직 안심하기는 이르다

바로 thisvalue 에 관한 것이다

분명 일치하면 그 값은 더이상 일치한 것을 감지하지 않게 해야 한다. 

즉 리스트에서 값을 삭제해야 하는 것이다.

인덱스로 삭제할려면 del 구문을 쓰면 된다.

def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        correct = 0
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
            for check in range(0, len(thisvalue)):
                if thisvalue[check] == thisinput:
                    correct += 1
                    del thisvalue[check]
                    break
    return finallist

그럼 correct 값은 정확하게 몇개의 글자가 일치하게 되는지 여부가 된다.


그럼 이제 finallist 에 append 로 일치하는 값을 추가하면 된다.


그럼 if 문 두개를 만들겠다.

def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(inputlist)):
        thisvalue = list(valuelist[valueindex])
        correct = 0
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
            for check in range(0, len(thisvalue)):
                if thisvalue[check] == thisinput:
                    correct += 1
                    del thisvalue[check]
                    break
        if len(inputlist) <= correct:
            finallist.append(valueindex)
        elif (len(inputlist) // 2) <= correct and len(inputlist) > 1:
            finallist.append(valueindex)
    return finallist

첫번째는 correct 가 검색한 값의 length 보다 맞은 개수 이상이면 최종 값에   valuelist의  인덱스를 추가한다.

두번째는 correct 가 검색한 값의 length 정수형 나누기  2  이상이면  최종 값에 valuelist의 인덱스를 추가한다.

이다 그렇게 뽑아낸 값은 finallist 에 들어간다.


그럼 어떻게 일치한 값들을 뽑아낼까?


우리가 뽑아낸 것은 valuelist 의 인덱스 값이기에 for 문으로 뽑아주면 완성이다.

def search(valuelist: list, inputlist: list):
    finallist = []
    for valueindex in range(0, len(valuelist)):
        thisvalue = list(valuelist[valueindex])
        correct = 0
        for inputindex in range(0, len(inputlist)):
            thisinput = inputlist[inputindex]
            for check in range(0, len(thisvalue)):
                if thisvalue[check] == thisinput:
                    correct += 1
                    del thisvalue[check]
                    break
        if len(inputlist) <= correct:
            finallist.append(valueindex)
        elif (len(inputlist) // 2) <= correct and len(inputlist) > 1:
            finallist.append(valueindex)
    return finallist

valist = ["개발", "깃허브"]
inlist = ["개"]
searchvalue = search(valist, inlist)
for i in range(0, len(searchvalue)):
    print(valist[i])

이렇게 작성하면 "개발" 이라는 값을 얻을 수 있다.

281b357d7d0c2fbc2d3a2f2a78bf52fe.PNG

이로서 검색의 기본적인 기능을 알고리즘으로 구현 했다.


다음에는 yaml 에 검색값을 저장하고 꺼내쓰는 코드를 알려드리겠습니다.

강의에서 질문이나 이해 안가는 내용 있으시면 설명해드리겠습니다.

마지막 코드만 복사해 가져가는 것은...

그리고 반응 좋으면 다음 편 합니다. ㅂㅂ

9f5942844df746cb3849a7302c0de859.png

4개의 댓글

마크러버
2020.05.31

와우 몰랐네요

추천 ㄱㄱ

logdev
2020.05.31
@마크러버

다중 for 문은 초보자에겐 뭣 같을 수 있으니 아예 다중 for 에 대한 이해가 없다면 이해가 어려울 겁니다. 추천 감사합니다.

logdev
2020.05.31

그리고 중간에 주석 처리된 것 같은 부분이 있는데, 파이썬에선 주석이 # 이기 때문에 그냥 보시면 됩니다.

뉴스 및 창작물
/files/thumbnails/762/770/003/262x150.crop.jpg?20240418073724

레드스톤

T.B.H (고민중독) | 노트블럭 버전 | NoteBlock Cover [한국어 영어 중국어 가사 추가]

노트블럭전문가

2024-04-18

0

/files/thumbnails/218/767/003/262x150.crop.jpg?20240412130213

레드스톤

우리의 꿈 - 원피스 오프닝

노트블럭전문가

2024-04-12

0

/files/thumbnails/505/766/003/262x150.crop.jpg?20240411122306

레드스톤

기동전사 건담 수성의 마녀 | 노트블럭 커버 1

노트블럭전문가

2024-04-11

1

/files/thumbnails/932/765/003/262x150.crop.jpg?20240410124459

레드스톤

마인크래프트 노트블록으로 만든 『 밤양갱 (Bam Yang Gang) 』

노트블럭전문가

2024-04-10

0

/files/thumbnails/403/765/003/262x150.crop.jpg?20240409190538

레드스톤

마인크래프트 노트블록으로 만든 『 밤양갱 (Bam Yang Gang) 』

Sonttukk

2024-04-09

4