[파이썬 알고리즘] 가장 흔한 단어

tester·2021년 1월 25일

알고리즘

목록 보기
5/26

가장 흔한 단어

금지된 단어를 제외한 가장 흔하게 등장하는 단어를 출력하라. 대소문자 구분을 하지 않으며, 구두점(마침표, 쉼표)또한 무시한다.

입력

paragraph = "Bob hit a ball, the hit BALL flew far after it was hit."

출력

"ball"

code: most_common.py

이 문제를 푸는 방법은 다양하지만, 파이썬의 장점을 살릴 수 있는 풀이를 알아보자.

먼저, 데이터의 전처리 과정에서 대소문자의 구분과 구두점을 없애기 위해 정규식을 사용할 수 있다.

[word for word in re.sub(r'[^\w]', ' ', paragraph)
    .lower().split()
    if word not in banned]

정규식에서 ^not, \wword를 뜻한다. 따라서, sub 메소드를 통하여 정규식에 해당되는 word가 아닌 paragraph의 문자는 공백으로 치환된다.

그 후, 해당 paragraph는 lower 된 다음 split된다.

split 된 결과물은 전처리된 paragraph 문자열이 공백을 기준으로 나뉜 word의 list가 될것이다.

해당 list를 for in 문을 통해 각각의 단어에 대해 not in banned인지 검사 하고, 통과된다면, 최종적으로 []안에 삽입된다.

해당 구문에 대한 가독성이 뛰어나다고 할 수는 없지만, 천천히 뜯어보면 이해하기 어렵지 않고, 작성하기도 쉬운 코드이다.

개수를 처리하는 부분은 두 가지 방법이 있다.


첫번째는 dict를 활용하는 방법인데, collections.defaultdict(int)를 통해 개수를 담는 변수가 int 기본값이 자동으로 부여되게 한다.

counts = collections.defaultdict(int)
for word in words:
    counts[word] += 1

이렇게 하면, 해당 키가 개수를 count하는 dict에 존재하는지 검사할 필요 없이, 자동으로 0의 기본값이 부여된 것에 +=1 처리를 해줄 수 있다.

그 후, max 메소드를 사용하여 딕셔너리에서 값이 가장 큰 키를 가져온다.

max 메소드는 기본적으로 dictionary의 각 key의 값 중에서 가장 큰(ASCII값)것을 검사하지만, key를 지정하여 각 key값이 어떻게 적용될 지 설정할 수 있다.

여기에서는, key값을 get하여 그 중에서 가장 큰 값이 return 되도록 한다.

return max(counts, key=counts.get)
# 위의 코드는
# max(counts, key=lambda key: counts[key])
# 와 같다.

다음 방법으로, dict에서 개수를 처리하는 부분은 Counter 모듈을 사용할 수 있다.

counter 모듈의 most_common(n) 메소드는 해당 counter 안의 가장 빈도수가 높은 n개를 list안의 tuple 형태로 반환한다.


[('a', 3)]

의 형태이다.

따라서 주어진 문제에서 most_common(1)로 가장 빈도수가 높은 것을 가져오고 [0][0]의 인덱스인 list안의 tuple의 첫 요소를 가져오면 된다.

counts = collections.Counter(words)
return counts.most_common(1)[0][0]

전체 코드는 다음과 같다.

def mostCommon(paragraph, banned):
    words = [word for word in re.sub(r'[^\w]', ' ', paragraph)
             .lower().split()
             if word not in banned]

    counts = collections.Counter(words)
    print(counts)
    return counts.most_common(1)[0][0]
profile
모듈깎는 장인이 되고싶다

0개의 댓글