ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [코딩도장] day20. 회문 판별과 N-gram 만들기
    IT/파이썬 2020. 9. 12. 01:44

    ■ 들어가기

    - 파이썬 코딩 도장 (남재윤/길벗). 을 공부하며 정리하는 블로그


    ▶ Unit28. 회문 판별과 N-gram 만들기

         - 28.1 회문 판별하기

         - 28.2 N-gram 만들기

     

    >> 28.1 회문 판별하기 <<

    1. 회문 판별하기

    - 회문(palindrome) : 순서를 거꾸로 읽어도 제대로 읽은 것과 같은 단어 또는 문장을 의미

    - 예) "level", "SOS", ...

     

    2. 반복문으로 문자 검사하기

    소스 (palindrome.py) 결과
    word = input('단어를 입력하세요: ')

    is_palindrome = True
    for i in range(len(word) // 2) :    # 버림 나눗셈 : 나눗셈 결과에서 소수점 이하 버림
        if word[i] != word[-1-i] :     # 뒤에서부터 인덱스 찾을 때는 -1, -2, .. 로 확인
            is_palindrome = False
            break
        
    print(is_palindrome)
    단어를 입력하세요: level
    True

    단어를 입력하세요: abc
    False

    - 문자열의 마지막 문자는 인덱스 -1이며, 여기서 -1씩 빼주면 오른쪽 -> 왼쪽으로 이동 (참고: 시퀀스 자료형 - 4.인덱스 사용하기)

    - 즉, 파이썬에서 음수 인덱스는 뒤에서부터 요소 접근 가능!

     

    3. 시퀀스 뒤집기로 문자 검사하기

    - 시퀀스 객체의 슬라이스 활용

    소스 (palindrome_slice.py) 결과
    word = input('단어를 입력하세요: ')

    print(word == word[::-1])   # 원래 문자와 반대로 뒤집은 문자열 비교
    단어를 입력하세요: level
    True

    단어를 입력하세요: abc
    False

    - 슬라이스는 시퀀스 객체의 일부를 잘라내는 기능으로 "시퀀스객체[시작인덱스:끝인덱스"의 형식으로 사용함 (참고: 시퀀스 자료형 - 슬라이스)

    - 특히 "시퀀스객체[::증가폭]" 의 형식은 "리스트 전체"에서 증가폭만큼 증가하면서 요소 가져오는 방식임

     

    4. 리스트와 reversed 사용하기

    - 객체 요소 순서를 반대로 뒤집는 reversed 사용

    >>> word = 'level'
    >>> list(word) == list(reversed(word))
    True
    >>> list(word)
    ['l', 'e', 'v', 'e', 'l']
    >>> list(reversed(word))
    ['l', 'e', 'v', 'e', 'l']

     

    5. 문자열의 join 메서드와 reversed 사용하기

    - join 메서드는 구분자 문자열과 문자열 리스트의 요소를 연결 (참고: 문자열 응용하기 - 4. 구분자 문자열과 문자열 리스트 연결하기)

    - 즉, 요소 사이사이에 구분자를 넣음

    >>> word = 'level'
    >>> word == ''.join(reversed(word))   # 빈 문자열 ''을 reversed(word)의 요소 사이에 끼워넣음 => reversed(word)와 동일
    True

    >> 28.2 N-gram 만들기 <<

    - N-gram : 문자열에서 N개의 연속된 요소를 추출하는 방법

    - 즉, 문자열의 처음부터 문자열의 끝까지 한 글자씩 이동하면서 N개씩 추출

     

    1. 반복문으로 N-gram 출력하기

    소스 (2_gram_character.py) 결과
    text = 'Hello'

    # 문자열의 끝에서 한 글자 앞까지 반복 (2-gram)
    for i in range(len(text) - 1) :
        print(text[i], text[i+1], sep='')
    He
    el
    ll
    lo

    - 문자열의 처음부터 한 칸씩 이동하면서 문자열의 끝에서 N-1번째 글자까지 N개씩 출력

    - 만일, 3-gram이라면 range(len(text) - 2)이 되어야 하며, 문자열의 끝에서 두 글자 앞까지 반복

     

    소스 (2_gram_word.py) 결과
    # 단어 단위 N-gram
    text = 'this is python script'
    word = text.split() # 공백을 기준으로 문자열을 분리 후 리스트로 만듦

    # print(word)
    # ['this', 'is', 'python', 'script']

    # 2-gram이므로 리스트의 마지막요소에서 한 개 앞까지만 반복
    for i in range(len(word) - 1) :
        print(word[i], word[i+1])
    this is
    is python
    python script

     

    2. zip으로 2-gram 만들기

    소스 (2_gram_character_zip.py) 결과
    text = 'hello'

    two_gram = zip(text, text[1:])
    for i in two_gram :
        print(i[0], i[1], sep='')
    he
    el
    ll
    lo

    - zip함수는 반복 가능한 객체의 각 요소를 튜플로 묶어줌 (즉, 콤마로 구분해서 넣어줌)

    - text는 hello, text[1:]는 ello 이므로 text, text[1:]의 각 요소를 튜플로 묶음

    - zip으로 묶는 첫 번째 리스트를 기준으로 더 묶을 요소가 없을 때까지 반복함

    >>> text = 'hello'
    >>> print(text[1:])
    ello
    >>> text
    'hello'
    >>> two = zip(text, text[1:])  # 요소의 수가 적은 리스트 기준으로 더 이상 묶을 수 없을 때까지 반복
    >>> for i in two :
    print(i)


    ('h', 'e')
    ('e', 'l')
    ('l', 'l')
    ('l', 'o')
    >>> two1 = zip(text[1:], text)
    >>> for i in two1 :
    print(i)


    ('e', 'h')
    ('l', 'e')
    ('l', 'l')
    ('o', 'l')
    >>> two2 = zip(text[2:], text[1:], text) # 요소가 적은 text[2:]를 기준으로 요소를 묶을 수 있을 때까지 반복하여 튜플 생성
    >>> for i in two2 :
    print(i)


    ('l', 'e', 'h')
    ('l', 'l', 'e')
    ('o', 'l', 'l')

    - 단어 단위 2-gram 확인

    >>> text = 'this is python script'
    >>> text.split()
    ['this', 'is', 'python', 'script']
    >>> words = text.split()
    >>> words
    ['this', 'is', 'python', 'script']
    >>> list(zip(words, words[1:]))
    [('this', 'is'), ('is', 'python'), ('python', 'script')]

     

    3. zip과 리스트 표현식으로 N-gram 만들기

    더보기

    - N-gram의 N이 늘어남에 따라 슬라이스 시작인덱스를 무한정 입력은 불가능하므로

    - 리스트 표현식을 사용해서 코드화함

    >>> text = 'hello'
    >>> [text[i:] for i in range(3)]   # 3-gram 표현
    ['hello', 'ello', 'llo']
    >>> list(zip(*[text[i:] for i in range(3)]))   # 리스트 앞에 * 를 붙혀서 리스트의 각 요소를 콤마로 구분해서 넣어줌
    [('h', 'e', 'l'), ('e', 'l', 'l'), ('l', 'l', 'o')]

    - 리스트에 * 를 붙히는 방법은 리스트 언패킹(list unpacking)이라 하며, "30.1 위치인수와 리스트 언패킹 사용하기"에서 자세히 다룸

    -> 솔직히 이 부분은 모르겠다.. T-T

     

    댓글

Designed by Tistory.