문자열

1주차에서 우리는 문자열을 받는 input()과 input().split()에 대해 배웠습니다. 이번에는 이 문자열을 다루는 법에 관해 공부하고 문제를 풀어보려고 합니다.

문자열의 연산

문자열의 연산은 더하기(+)와 곱하기(*) 기능을 사용할 수 있습니다. 이 기능의 역할은 숫자의 연산과 비슷하게 작동합니다.

1000+12341000 + 1234

위와 같은 식이 있다고 생각해봅시다. 이 식을 계산하는 과정은 더하기가 있으므로 1000과 1234를 합쳐서 2234라는 답을 보여줍니다.

문자열도 비슷합니다.

print('a' + 'b')

위와 같은 코드가 있을 때, 더하기가 있으므로 'a'와 'b'를 합쳐서 'ab'라는 문자열을 만들어냅니다. 숫자의 덧셈에서는 새로운 수를 만들어내는 것과 비슷하게 문자의 덧셈에서는 새로운 문자열을 만들어냅니다.

a = 'hel'
b = 'lo'
c = a + b + '?'
print(c)
# hello?를 출력

이렇게 변수에 문자열을 넣어서 새로운 변수에 값을 저장할 수 있습니다.

내용은 이게 끝입니다. 빠르게 곱하기로 넘어가 봅시다. 곱하기도 숫자의 곱셈과 비슷합니다.

232 * 3

2 * 3이라는 식은 2 + 2 + 2 = 6로 2를 3번 더하여 6이라는 값을 도출해내는 방식을 사용하고 있습니다.

문자열에서도 비슷합니다.

print('a' * 3)

'a' * 3은 숫자의 곱셈처럼 'a'를 세 번 더하여 'a' + 'a' + 'a' = 'aaa'라는 새로운 문자열을 얻을 수 있습니다.

a = 'red'
b = 'blue'
c = a * 3 + b * 2
print(c)
# redredredblueblue

문자열의 덧셈과 똑같이 문자열의 곱셈을 이용하여 변수에 새로운 값을 넣을 수도 있습니다.

바로 문제를 풀어봅시다.

문자열 바로 뒷부분에 ??!를 합쳐서 출력하라고 합니다.

그러면 먼저 문자열을 입력받고, 더하기 연산자를 이용하여 '??!'를 합치면 됩니다.

s = input()
print(s + '??!')

풀어 볼 문제

인덱싱(indexing)

인덱싱은 가르키다라는 뜻을 가지고 있습니다. 문자열에서의 인덱싱은 문자 하나하나를 가르킬 수 있다고 생각하시면 됩니다.

인덱싱을 사용하는 방법은 '문자[숫자]'로 사용하고 있습니다. 숫자는 문자열에서 글자의 순서를 나타냅니다. for문처럼 0부터 시작합니다.

s = 'hello'

변수[숫자]

문자

s[0]

h

s[1]

e

s[2]

l

s[3]

l

s[4]

o

이렇게 각각의 문자들은 위와 같은 숫자 값들을 가지고 있습니다.

이 값은 음수를 가질 수도 있습니다. 음수를 가질 경우 거꾸로 맨 오른쪽 글자에서 시작하여 숫자가 작아질수록 왼쪽으로 이동합니다.

s = 'hello'
print(s[-1]) # o
print(s[-4]) # e

이렇게 s[-1]은 맨 오른쪽 첫 번째 글자로 o를 출력하게 되고, s[-4]는 왼쪽으로 더 가서 e라는 값을 출력하게 됩니다.

변수[숫자]

문자

s[-1]

o

s[-2]

l

s[-3]

l

s[-4]

e

s[-5]

h

괄호 안에 들어가는 값은 숫자면 무엇이든지 가능하므로 int값이 저장된 변수도 넣을 수 있습니다.

s = 'I am student'
x = 6
print(s[x]) # t

이제 문제를 풀어야 하는데 먼저 len()이라는 함수에 대해 알고 지나가야 합니다.

len()에 대한 자세한 내용은 3주차에서 다룰 예정이고, 지금은 len을 이용하는 한 가지 방법만 배우려고 합니다. 이 내용도 3주차에 다시 알려드립니다.

len()

len()은 이번 주에 배우는 문자열과 리스트와 튜플, 다음 주에 배우는 딕셔너리, 셋등의 길이를 반환해줍니다.

s = 'hello'
print(len(s))

이런 코드가 있으면 s의 길이는 hello 다섯 글자이므로 5를 출력하게 됩니다.

s = 'I am student'
print(len(s))

이런 코드가 있으면 공백까지 포함하여 12글자이므로 12를 출력합니다.

여기에서 사용할 내용은 for문의 range()안에 있는 숫자를 넣기 위해서 사용합니다.

s = 'abcde'
for i in range(len(s)):
    blah blah

위와 같은 코드가 있으면 len(s) = 5이므로 for문이 5번 돌아간다는 것입니다.

이 내용만 알고 있으면 됩니다. len 함수는 바로 다음에 배울 리스트에서도 사용합니다.

이제 문제를 풀어봅시다.

문자열이 주어질 때, 모음의 개수가 총 몇 개인지 구하는 문제입니다.

입력값을 받을 때, #을 입력 받으면 끝나므로 while문을 이용해야 합니다. 그리고 모음의 개수를 모두 더할 변수도 하나 필요하겠네요. 일단 이 내용과 문자열을 입력 받는 코드를 만들어봅시다.

while True:
    s = input()
    if s == '#': break
    ans = 0

이제 문장에서 모음의 개수를 확인해야 하는데, 위에서 배운 len()으로 문자열의 길이만큼 for문을 돌려주고 인덱싱 기능과 if문을 이용하여 모음인지 확인할 수 있습니다.

여기서 주의할 점은 대문자, 소문자를 받을 수 있다는 점입니다. 그래서 문자를 a, e, i, o, u, A, E, I, O, U 총 10개의 글자를 비교해서 같은 글자가 있는지 확인해봐야 합니다.

while True:
    s = input()
    if s == '#': break
    ans = 0
    
    for i in range(len(s)):
        if s[i] == 'a' or s[i] == 'e' or s[i] == 'i' or s[i] == 'o' or s[i] == 'u':
            ans += 1
        if s[i] == 'A' or s[i] == 'E' or s[i] == 'I' or s[i] == 'O' or s[i] == 'U':
            ans += 1
    
    print(ans)

풀어볼 문제

슬라이싱(slicing)

슬라이싱은 자른다는 의미를 가진 단어입니다. 문자열에서의 슬라이싱은 문자열에서 원하는 문자열만큼 떼올 수 있는 기능을 가지고 있습니다.

문자열의 슬라이싱 은 for문의 range와 문자열의 인덱싱 기능이 합쳐진 것이라고 생각하면 쉽습니다.

사용 방법은 '문자열[start:end]', '문자열[start:end:step]'인데, for문과 비슷하게 start 값부터 end - 1까지의 문자열을 가지고 옵니다. 문자열[start:end]의 경우에는 문자열[start,end:1]과 같은 뜻을 지니고 있습니다.

s = 'hello'
print(s[1:3]) # el

위와 같이 s[1:3]이면 s[1]+s[2] = el 을 출력하게 됩니다.

s = 'hello'
print(s[1:99]) # ello

이렇게 문자열의 길이보다 큰 값을 end값에 입력을 해도 파이썬은 문자열의 끝부분까지만 인식하여 ello를 출력합니다.

s = 'hello'
print(s[-3: 5]) # llo

start의 값이 음수인 경우엔 양수로 가리킬 때의 값으로 인식합니다. 그래서 -3을 입력해도 2로 인식됩니다.

s[-3: 5]는 s[2:5]이므로 llo를 출력하지만, s[-3:1]은 s[2:1]이기 때문에 아무것도 출력하지 않습니다.

s = 'hello'
print(s[:3]) # hel
print(s[2:]) # llo
print(s[:]) # hello

위와 같이 start와 end에 값이 없을 때, start는 맨 왼쪽 글자의 인덱스 값인 0을 나타내고 end의 경우에는 맨 오른쪽 글자의 인덱스 값 + 1인 5를 나타냅니다. end의 값의 경우에는 문자열의 길이마다 달라지겠네요.

s = 'hello'
print(s[::2]) # hlo

step에 x값을 주면 x값씩 건너뛰고 문자를 출력합니다. 그래서 윗 코드와 같이 step = 2인 경우에는 첫 번째 글자인 h, 세 번째 글자인 l, 다섯 번째 글자인 o를 합쳐서 출력합니다.

보통 step이 쓰일 때는 문자열을 뒤집어서 출력해야 할 때 많이 사용됩니다.

s = 'hello'
print(s[::-1]) # olleh

이렇게 [::-1]을 적어서 olleh를 출력할 수 있습니다.

슬라이싱에서 만든 것도 문자열에 속하기 때문에 문자열의 연산과 인덱싱을 사용할 수 있습니다. 그리고 아래에서 배우는 메서드들도 그대로 사용할 수 있습니다.

s = 'akbkckdkkekfkg'
print(s[:8:2] + s[9::2]) #abcdefg 출력

s = 'abcde'
print(s[1::][0] * 3) # bbb 출력

이제 문제를 풀어봅시다.

10개의 글자씩 끊어서 출력하라고 합니다.

이 문제는 for문의 range의 값을 (0, len(s), 10)으로 설정하고, 문자열은 슬라이싱 기능을 이용하여 출력하면 됩니다.

s =input()
for i in range(0, len(s), 10):
    print(s[i:i+10])

풀어볼 문제

대문자, 소문자 변환 메서드

문자열의 메서드에는 알파벳을 대문자, 소문자로 변환시키는 메서드가 있습니다.

대문자로 변환하는 메서드는 upper입니다. upper는 알파벳 소문자들을 대문자로 만드는 기능을 가지고 있습니다. 문자열 안에 알파벳이 아닌 다른 문자에는 전혀 영향을 끼치지 않습니다.

s = 'gOodBye..'
print(s.upper()) #GOODBYE..

gOodBye라는 문자열에 upper 메서드를 사용하면 이미 대문자인 O, B는 그대로 있고, 소문자인 g, o, d, y, e가 대문자로 바뀌게 됩니다. ..은 알파벳이 아니므로 바뀌지 않습니다.

소문자로 변환하는 메서드는 lower입니다. lower는 알파벳 대문자를 소문자로 만드는 기능을 가지고 있습니다. 그리고 lower 역시 문자열 안에 알파벳이 아닌 다른 문자에는 전혀 영향을 끼치지 않습니다.

s = 'HELlO!!'
print(s.lower()) #hello!!

대문자인 H, E, L, O는 소문자로 바뀌게 됩니다. 그리고 l, !!는 아무것도 바뀌지 않습니다.

이제 문제를 풀어봅시다.

문자열에서 니모를 찾아야 하는 문제입니다.

대소문자는 중요하지 않다고 하므로 Nemo, nEMo, nemo, NEMO 뭐든 상관 없다는 뜻입니다. 그래서 문자열을 전부 소문자나 대문자로 바꾸어서 문제를 풀 수 있습니다. 여기에서는 문자열을 소문자로 변환하겠습니다.

while True:
    s = input()
    if s == 'EOI': break
    s = s.lower()

이제 nemo를 찾아야 하는데 이것은 슬라이싱 기능을 이용하여 풀 수 있습니다. 그리고 for문을 이용하면 되겠네요.

그리고 문장안에 nemo가 있는지 판별해서 출력해야 하므로 flag라는 변수를 하나 만들어줍시다. 기본값은 nemo를 찾지 못했으므로 False라고 하고, nemo를 찾으면 True로 값을 변경하고 break문을 통해 빠져나옵니다.

while True:
    s = input()
    if s == 'EOI': break
    s = s.lower()

    flag = False
    for i in range(len(s)):
        if s[i:i+4] == 'nemo':
            flag = True
            break #break문은 없어도 가능
    if flag == True: print('Found')
    else: print('Missing')

풀어볼 문제

그 외 메서드

isupper / islower

해당 문자열이 전부 대문자로 이루어져 있는지 / 전부 소문자로 이루어져 있는지 True, False 값으로 반환해주는 메서드입니다.

s = 'HELLO'
print(s.isupper()) # True
print(s.islower()) # False

s = 'byebye'
print(s.isupper()) # False
print(s.islower()) # True

s = '1234?!'
print(s.isupper()) # False
print(s.islower()) # False

s = 'aAbBcC'
print(s.isupper()) # False
print(s.islower()) # False

find

문자열에서 찾고 싶은 문자가 있을 때, find('문자')를 사용하여 인덱스 값을 반환 시켜줍니다. 이때 문자열 안에 찾고 싶은 문자가 여러 개가 있을 경우에는 인덱스 값이 가장 작은 값을 반환합니다.

s = 'phone'
print(s.find('n')) # 3

s = 'banana'
print(s.find('n')) # 2

count

문자열에서 찾고 싶은 문자가 문자열 안에 총 몇 개가 있는지 반환하는 메서드입니다.

s = 'coffee'
print(s.count('f')) # 2

s = 'aaaaaaa'
print(s.count('a')) # 7

Last updated