Python 기초

문자열

문자열(string)은 프로그래밍에서 아주 빈번하게 다루어지는 데이터 형식입니다. 문자열은 문자열의 시퀀스로 정의됩니다.

글자들이 실(string)로 묶여 있는 것이 문자열이라고 생각하면 됩니다.

 

파이썬에서는 str 클래스가 문자열을 나타냅니다. str 클래스는 파이썬의 내장 클래스입니다.

파이썬에서 문자열 리터럴은 작은 따옴표나 큰 따옴표로 감싸서 표현합니다.

문자열은 str 클래스의 생성자를 호출하여서 생성할 수도 있고 아니면 문자열 리터럴을 이용하여 생성하여도 됩니다.

s1 = str("Hello")
s2 = "Hello"

 

문자열은 변경 불가능한 객체입니다. 문자열 객체가 생성되면 객체는 더 이상 변경될 수 없습니다.

문자열은 변경될 수 없기 때문에, 변경된 문자열이 필요하면 새로운 문자열 객체를 생성하게 됩니다.

예를 들어 수식 ("Hello" + "World") 는 "Hello" 와 "World" 문자열 객체를 합쳐서 새로운 문자열 객체인 "HelloWorld" 를 생성합니다.

s1 = "Hello"
s2 = "World"
s3 = "Hello"+"World"

 

문자열도 크게 보면 시퀀스(sequence)라는 자료구조에 속합니다.

따라서 우리가 앞에서 학습하였던 인덱싱이나 슬라이싱과 같은 연산들과 len()과 같은 내장 함수들이 모두 적용됩니다.

 

개별 문자 접근하기

문자열은 문자들로 이루어져 있습니다. 무자열 중에서 하나의 문자를 추출하려면 어떻게 해야 할까요? 예를 들어서 암호화 프로그램에서는 문자열에서 하나의 문자를 추출하는 것이 필요합니다.

인덱싱(Indexing)이란 문자열에 [ 와 ] 를 붙여 문자를 추출하는 것입니다. [ 와 ] 사이에는 인덱스가 들어갑니다.

word = 'abcdef'
print(word[0])
print(word[5])

 

<실행 결과>

a
f

 

인덱스(index)는 문자열에 포함된 각각의 문자에 매겨진 번호입니다. 예를 들어 문자열 "abcdef" 에서 각 문자의 인덱스는 다음과 같습니다.

인덱스는 문자에 매겨진 번호이며 0부터 시작합니다.

a b c d e f
0 1 2 3 4 5

 

첫 번째 문자의 인덱스는 0입니다. 두 번째 문자는 1이고 세 번째 문자는 2가 됩니다.

인덱스에서 혼동하기 쉬운 부분이 0부터 시작한다는 점입니다. 1부터 시작되는 것이 아닙니다.

인덱스는 음수가 될 수 있습니다. 이것은 파이썬의 특별한 기능입니다. 인덱스가 음수가 되면 오른쪽에서 왼쪽으로 번호가 매겨집니다.

음수 인덱스도 굉장히 편리하므로 꼭 기억해두시기 바랍니다.

a b c d e f
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1

 

word = 'abcdef'
print(word[-1])
print(word[-6])

 

<실행 결과>

f
a

 

-0과 0은 동일하기 때문에 음수 인덱스는 -1부터 시작합니다. 인덱싱에서 너무 큰 인덱스를 사용하게 되면 오류가 발생합니다.

word = 'abcdef'
print(word[10])

 

<실행 결과>

IndexError: string index out of range

 

파이썬 문자열은 변경 불가능한 객체입니다. 따라서 다음과 같이 문자열의 일부 글자를 바꾸려고 하면 오류가 발생합니다.

word = 'abcdef'
word[0] = 'A'

 

<실행 결과>

TypeError: 'str' object does not support item assignment

 

슬라이싱

문자열에서 여러 개의 문자들을 추출할 수 있을까요? 파이썬 문자열에는 슬라이싱(slicing)도 지원됩니다.

슬라이싱이란 문자열의 일부를 잘라서 서브 문자열을 만드는 연산으로 파이썬의 두드러진 장점 중의 하나입니다.

슬라이싱을 이용하면 내가 원하는 부분을 쉽게 잘라낼 수 있습니다.

 

slicing gif에 대한 이미지 검색결과

챱-챱

 

설명을 위하여 다음과 같이 변수에 문자열이 저장되어 있다고 합시다.

s = "Hello World"

 

위의 문자열에서 첫 번째 단어 "Hello"를 추출하고 싶으면 아래와 같이 합니다.

s = "Hello World"
print(s[0:5])

 

<실행 결과>

Hello

 

위의 문장에서 s[0:5]은 문자열 s의 특정 구간을 나타내는 수식으로 "0부터 4까지"의 구간을 의미합니다. 0이 시작 위치이고 5가 종료 위치입니다.

종료 위치 5는 구간에 포함되지 않는다는 것에 주의해야 합니다. 이렇게 콜론(:)을 이용하여 특정한 구간을 지정하는 것이 슬라이싱입니다.

 

python slicing에 대한 이미지 검색결과

 

슬라이싱이 동작되는 원리를 쉽게 기억하려면 인덱스가 문자들 사이에 있다고 생각하는 것입니다.

첫 번째 문자의 왼쪽 엣지의 번호는 0이 됩니다. 마지막 문자의 오른쪽 엣지는 인덱스 n이 됩니다. 여기서 n은 문자열의 크기입니다.

위의 그림에서 첫 번째 번호들은 음수 인덱스를 보여주고 있습니다. 두 번째 줄의 번호들은 0부터 6까지의 위치를 보여주고 있습니다.

슬라이싱 [i:j]는 i번째 엣지부터 j번째 엣지 사이에 있는 문자들을 추출합니다.

word = "Python"
print(word[0:2])
print(word[2:5])

 

<실행 결과>

Py
tho

 

시작 인덱스가 생략되면 문자열의 처음이라고 가정됩니다. 문자열의 마지막까지 지정하려면 종료 인덱스를 생략하면 됩니다.

word = "Python"
print(word[:2])
print(word[4:])

 

<실행 결과>

Py
on

 

문자열 s에서 s[:i] + s[i:] 연산을 하면 항상 s와 같아집니다.

word = "Python"
print(word[:2] + word[2:])
print(word[:4] + word[4:])

 

<실행 결과>

Python
Python

 

또 시작 인덱스와 종료 인덱스가 모두 생략되면 문자열 전체가 선택됩니다. 예를 들어 word[:] 라고 하면 word의 모든 문자가 선택됩니다.

word = "Python"
print(word[:])

 

예를 들어 만약 문자열을 5번째 문자를 기준으로 둘로 나눠서 high, low에 저장하고 싶다면 아래와 같이 하면 될 것입니다.

message = 'when i see you again'
low = message[:5]
high = message[5:]

print(low)
print(high)

 

<실행 결과>

when
i see you again

 

주민등록번호 앞자리에서 출생연도와 생일을 추출하여 화면에 출력해봅시다.

reg = "970124"
print(reg[0:2], "년")
print(reg[2:4], "월")
print(reg[4:6], "일")

 

<실행 결과>

97 년
01 월
24 일

 

음수가 아닌 인덱스를 사용하는 경우, 슬라이스의 길이는 인덱스의 차이입니다. 예를 들어 word[1:3]의 길이는 2입니다.

슬라이싱에서 시작 인덱스나 종료 인덱스로 적절히 못한 값을 사용하더라도 파이썬은 자동으로 적절한 값으로 변경하여 실행합니다.

word = 'Python'
print(word[4:42])
print(word[42:])

 

<실행 결과>

on
 

 

파이썬 문자열은 변경될 수 없습니다. 이것을 불변(immutable)하다고 합니다. 따라서 문자열의 인덱스 위치에 문자를 저장하는 것은 오류입니다.

word = 'Python'
word[2:] = 'py'

 

<실행 결과>

TypeError: 'str' object does not support item assignment

 

만약 다른 문자열이 필요하다면 개발자가 새로운 문자열을 생성하면 됩니다.

word = 'Python'
print('J' + word[1:])
print(word[:2] + 'py')

 

<실행 결과>

Jython
Pypy

 

내장 함수 len()은 문자열의 길이를 반환합니다.

s = "It's the end game"
print(len(s))

 

<실행 결과>

17

 

in 연산자와 not in 연산자

문자열 안에 다른 문자열이 있는지를 알아내기 위해서 in 연산자를 사용할 수 있습니다. 아래의 코드를 참조합시다.

s = "where the sky is blue see you once again"
print("blue" in s)
print("seulgi" in s)

 

<실행 결과>

True
False

 

in 연산자를 이용하여 여러 가지 예제를 쉽게 작성할 수 있습니다. 예를 들어 문자열에 특정 글자가 있는지를 확인하는 코드는 다음과 같습니다.

s = input("문자열을 입력하세요 : ")

if 'c' in s:
    print('c가 포함되어 있습니다.')
else:
    print('c가 포함되어 있지 않습니다.')

 

<실행 결과>

문자열을 입력하세요 : ohohohohohohohohohoh my lucky strike
c가 포함되어 있습니다.

 

문자열 비교하기

문자열과 문자열을 비교할 수 있을까요? 예를 들어 어떤 문자열이 사전에서 먼저 나오는지를 검사할 수 있을까요?

파이썬에서는 관계 연산자를 이용하여서 문자열과 문자열을 비교할 수 있습니다. 예를 들어 "apple"은 "banana"보다 사전에서 앞에 있습니다.

어떤 문자열이 사전에서 앞에 있으면 < 연산자를 적용했을 때 참이 됩니다.

print("apple" < "banana")

 

<실행 결과>

True

 

마찬가지로 ==, !=, <, > 연산자를 문자열에도 적용할 수 있습니다. 이것은 어디에 사용할 수 있을까요?

사용자로부터 받은 문자열들의 순서를 정할 때 사용할 수 있습니다. 그리고 문자열들의 정렬에도 사용할 수 있습니다.

a = input("문자열을 입력하세요 : ")
b = input("문자열을 입력하세요 : ")

if a < b:
    print(a, "이 앞에 있습니다.")
else:
    print(b, "이 앞에 있습니다.")

 

<실행 결과>

문자열을 입력하세요 : 꾸엑
문자열을 입력하세요 : 뿌엑
꾸엑 이 앞에 있습니다.

 

반복하여 문자 처리하기

문자열에 들어 있는 각각의 문자들에 대하여 어떤 연산을 반복할 수 있습니다. 예를 들어서 문자열 안에 모든 문자를 하나씩 출력하는 코드는 다음과 같습니다.

s = input("문자열을 입력하세요 : ")
for c in s:
    print(c)

 

<실행 결과>

문자열을 입력하세요 : ㄱㅡㄹㅜ
ㄱ
ㅡ
ㄹ
ㅜ

 

문자열 안의 문자들을 특정한 순서로 방문하기를 원한다면 인덱스 연산자를 사용하는 것이 편리합니다.

예를 들어서 홀수 번째 문자만을 방문하기 운한다면 다음과 같은 코드를 사용합니다.

s = input("문자열을 입력하세요 : ")

for i in range(1, len(s), 2):
    print(s[i])

 

<실행 결과>

문자열을 입력하세요 : abcdefg
b
d
f

 

이제까지는 문자열 객체에 연산자를 적용하는 방법만 설명하였습니다. 이제부터는 str 클래스가 가지고 있는 유용한 메소드에 대하여 알아봅시다.

우리가 클래스를 사용하는 이유는 다른 사람들이 작성한 유용한 메소드를 사용하기 위해서입니다.

 

문자열에서 단어 분리

문자열에서 단어를 분리할 때 사용하는 메소드는 split() 입니다. split() 은 문자열 안의 단어를 분리하여 단어들의 리스트로 만들어서 반환합니다.

s = "하 지금 교육 준비하는거 진짜 힘들다. 몇 시간째 이러고 있냐 정말 하 진짜 자괴감 들고 막 하 진짜"
print(s.split())

 

<실행 결과>

['하', '지금', '교육', '준비하는거', '진짜', '힘들다.', '몇', '시간째', '이러고', '있냐', '정말', '하', '진짜', '자괴감', '들고', '막', '하', '진짜']

 

split()은 기본적으로 스페이스 문자를 이용하여 단어들ㄹ을 분리합니다. 만약 분리자로 다른 문자를 사용하고 싶으면 split()의 인수로 전달하면 됩니다.

s = "하 지금 교육 준비하는거 진짜 힘들다. 몇 시간째 이러고 있냐 정말 하 진짜 자괴감 들고 막 하 진짜"
print(s.split('하'))

 

<실행 결과>

['', ' 지금 교육 준비', '는거 진짜 힘들다. 몇 시간째 이러고 있냐 정말 ', ' 진짜 자괴감 들고 막 ', ' 진짜']

 

문자열의 검사

문자열이 알파벳으로 구성되어 있는지 아니면 숫자로만 구성되어 있는지를 검사할 때는 isalpha()와 isdigit()을 사용할 수 있습니다.

s = "abcdef"
print(s.isalpha())

s = "123456"
print(s.isdigit())

 

<실행 결과>

True
True

 

유사한 메소드로 소문자인지를 검사하는 islower(), 대문자인지를 검사하는 isupper(), 공백문자로만 되어 있는지를 검사하는 isspace(), 영문+숫자인지 검사하는 isalnum() 등이 있습니다.

사용자에게서 연도를 입력받을 때 숫자인지를 검사하는 코드는 아래와 같습니다.

s = input("연도를 입력하세요 : ")

if not s.isdigit():
    print("숫자만을 입력해주세요!")
else:
    print(s)

 

<실행 결과>

연도를 입력하세요 : 힘들다
숫자만을 입력해주세요!

 

부분 문자열 검색

문자열 안의 부분 문자열을 찾기 위하여 startswith(s), endswith(s), find(s), rfind(s), count(s) 등의 메소드를 사용할 수 있습니다.

startswith(s)는 문자열 s로 시작되는 문자열이면 True가 반환됩니다. endswith(s)는 문자열 s로 종료되는 문자열이면 True가 반환됩니다.

예를 들어 사용자가 입력한 문자열이 파이썬 소스 파일 이름인지를 검사하려면 아래와 같이 합니다.

s = input("파이썬 소스 파일 이름을 입력하세요 : ")

if s.endswith(".py"):
    print("올바른 파일 이름입니다.")
else:
    print("올바른 파일 이름이 아닙니다.")

 

<실행 결과>

  • 문자열 "redvelvet.py" 를 입력했을 때
파이썬 소스 파일 이름을 입력하세요 : redvelvet.py
올바른 파일 이름입니다.

 

문자열 반환하기

문자열의 모든 문자를 대문자로 만들거나 소문자로 만들려면 upper()와 lower()를 사용합니다.

첫 번째 문자만을 대문자로 하려면 capitalize()를 사용합니다. 하나의 문자를 다른 문자로 바꾸려면 replace(s1, s2)를 사용합니다.

s = input("파이썬 소스 파일 이름을 입력하세요 : ")
print(s.lower())

 

<실행 결과>

파이썬 소스 파일 이름을 입력하세요 : RedVelvet.py
redvelvet.py

 

문자열에서 공백 문자 제거하기

공백 문자(whitespace character)란 스페이스나 탭, 줄바꿈 문자를 의미합니다. 문자열에서 공백 문자를 제거하려면 strip(), lstrip()이나 rstrip()을 사용합니다.

lstrip()은 왼쪽 공백 문자만을 제거하고 rstrip()은 오른쪽 공백 문자만을 제거합니다. strip()은 왼쪽과 오른쪽 공백 문자를 모두 제거합니다.

문자열 중간의 공백 문자는 제거되지 않습니다.

s = "     하하핳 ㅋㅋㅋㅋ    에휴    "
print(s.strip())

 

<실행 결과>

하하핳 ㅋㅋㅋㅋ    에휴

 

도전 과제

1. 회문(palindrome)은 앞으로 읽으나 뒤로 읽으나 동일한 문장입니다. 예를 들어 "mom", "civic", "dad" 등이 회문의 예입니다.

사용자로부터 문자열을 입력받고 회문인지를 검사하는 프로그램을 작성하여 봅시다.

 

<실행 결과>

  • 문자열 "asdfdsa" 를 입력했을 때
문자열을 입력하세요 : asdfdsa
회문입니다.

 


2. 머리 글자어(acronym)는 LoL(League of Legends) 처럼 각 단어의 첫 글자를 모아서 만들 문자열입니다.

사용자가 문장을 입력하면 해당되는 머리 글자어를 출력하는 프로그램을 작성하여 봅시다.

 

<실행 결과>

  • 문자열 "갑자기 붕어 싸만코" 를 입력했을 때
문자열을 입력하세요 : 갑자기 붕어 싸만코
갑붕싸
  •  문자열 "red velvet"을 입력했을 때
문자열을 입력하세요 : red velvet
RV

 


3. 봉민이는 석가탄신일에 딱히 할 일이 없어 이메일 주소에서 아이디와 도메인을 구분하는 프로그램을 만들었습니다.

아래의 실행 결과가 나오도록 프로그램을 작성하여 봅시다.

 

<실행 결과>

이메일 주소를 입력하세요 : 1reds@naver.com
1reds@naver.com
     1reds
     naver.com

 


4. 문자열 안에 있는 문자의 개수, 숫자의 개수, 공백의 개수를 계산하는 프로그램을 딕셔너리와 문자열 함수를 이용하여 작성하여 봅시다.

 

<실행 결과>

문자열을 입력하세요 : please don't see just a boy caught up in dreams and fantasy
{'alphas': 47, 'digits': 0, 'spaces': 11}