28.3 연습문제 : 단어 단위 N-gram 만들기
표준 입력으로 정수와 문자열이 각 줄에 입력됩니다. 다음 소스 코드를 완성하여 입력된 숫자에 해당하는 단어 단위 N-gram을 튜플로 출력하세요(리스트 표현식 사용). 만약 입력된 문자열의 단어 개수가 입력된 정수 미만이라면 'wrong'을 출력하세요.
n = int(input()) # 7 입력
text = input() # 'Python is a programming language that lets you work quickly' 입력
words = text.split()
if len(words) < n :
print('worng')
else:
a = list(zip(*[words[i:] for i in range(n)]))
for i in a:
print(i)
::
('Python', 'is', 'a', 'programming', 'language', 'that', 'lets')
('is', 'a', 'programming', 'language', 'that', 'lets', 'you')
('a', 'programming', 'language', 'that', 'lets', 'you', 'work')
('programming', 'language', 'that', 'lets', 'you', 'work', 'quickly')
N-gram 만들기로 7-gram으로 튜플로 출력하려 한다.
1 번 : text.split() # 공백을 기준으로 입력된 text를 요소 9개의 1개짜리 리스트를 생성 및 할당
2번 : 입력된 문자열의 단어 갯수가 입력된 정수 미만이면 worng을 출력하는데
# 7-gram으로 출력하고자하는데 문자열의 갯수가 7 미만이면 애초에 7-gram으로 출력할 수 가 없다.
3번 : #['Python', 'is', 'a', 'programming', 'language', 'that', 'lets', 'you', 'work', 'quickly'] == words를 이용한 리스트 표현식
a = list(zip([words[i:] for i in range(7)])) # 0 ~ 6 반복
을 이용하면 우리가 원하는 7-gram이 아닌 단순 리스트에서 요소를 차례대로 반복하며 출력을 하게된다.
ex : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] ==> 6번 반복하여 인덱스가 i 만큼 올라가는 단순 반복으로 출력하게 된다.
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 1번 반복
[2, 3, 4, 5, 6, 7, 8, 9, 10] # 2번
[3, 4, 5, 6, 7, 8, 9, 10] # 3번
...
[6, 7, 8, 9, 10] # 6번 반복
따라서 zip에 리스트 각 요소에 ,(콤마)를 구분해서 넣을 수 있도록 *을 붙이면 된다.
words 리스트 안의
ex *[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7]
[2, 3, 4, 5, 6, 7, 8]
[3, 4, 5, 6, 7, 8, 9]
[4, 5, 6, 7, 8, 9, 10]
print(words) #['Python', 'is', 'a', 'programming', 'language', 'that', 'lets', 'you', 'work', 'quickly']
a = list(zip(*[words[i:] for i in range(n)]))
for i in a:
print(i)
list(zip([words[i:] for i in range(n)])) ## * 없을때
# [(['Python', 'is', 'a', 'programming', 'language', 'that', 'lets', 'you', 'work', 'quickly'],),
# (['is', 'a', 'programming', 'language', 'that', 'lets', 'you', 'work', 'quickly'],),
# (['a', 'programming', 'language', 'that', 'lets', 'you', 'work', 'quickly'],),
# (['programming', 'language', 'that', 'lets', 'you', 'work', 'quickly'],),
# (['language', 'that', 'lets', 'you', 'work', 'quickly'],),
# (['that', 'lets', 'you', 'work', 'quickly'],),
# (['lets', 'you', 'work', 'quickly'],)]
list(zip(*[words[i:] for i in range(n)])) ## * 있을때
# [('Python', 'is', 'a', 'programming', 'language', 'that', 'lets'),
# ('is', 'a', 'programming', 'language', 'that', 'lets', 'you'),
# ('a', 'programming', 'language', 'that', 'lets', 'you', 'work'),
# ('programming', 'language', 'that', 'lets', 'you', 'work', 'quickly')]
따라서 zip에 리스트 각 요소에 ,(콤마)를 구분해서 넣을 수 있도록 *을 붙이면 된다.