파이썬 자료형 – 문자열(String) & 시퀀스 자료형 기초

파이썬 자료형 – 2편 문자열(String)

프로그래밍 언어에 있어 숫자에 이은 핵심적인 자료형입니다. 문자열은 말 그대로 문자의 집합, 편하게 얘기해서 문장을 의미합니다. “세종대왕”, “The quick brown fox jumps over the lazy dog” 같은 것이 문자열이죠.

요것도 문자열
요것도 문자열

문자열 만들기

큰따옴표(“)만을 지원하는 C/C++과 자바와는 달리 파이썬에서는 홑따옴표(‘)도 지원합니다.

>>> s = "The quick brown fox jumps over the lazy dog"
>>> s
'The quick brown fox jumps over the lazy dog'

>>> s = 'The quick brown fox jumps over the lazy dog'
>>> s
'The quick brown fox jumps over the lazy dog'

큰따옴표와 홑따옴표 모두를 지원하기 때문에 문장 안에 홑따옴표 혹은 외따옴표를 넣어야할 때 굉장히 편합니다. 예를 들어 아래 문장을 문자열로 만들고 싶다면

Count Dukoo : “Good. Twice the pride, double the fall.”

자바에서는 아래와 같이 표기해야 합니다.

String str = "Count Dukoo : \"Good. Twice the pride, double the fall.\" "

자바에서는 기본적으로 큰따옴표와 큰따옴표 사이를 문자열로 인식하기 때문이지요. 반면 파이썬에서는 문장 내에 큰따옴표가 있다면 홑따옴표로 문자열을 만들어 주면 됩니다.

>>> s = 'Count Dukoo : "Good. Twice the pride, double the fall." '

그 반대의 경우는 큰 따옴표로 문자를 만들면 되겠죠.

이 두 가지 방법 외에 두 가지 방법이 더 있습니다. 바로 홑따옴표를 세 번 연속으로 사용하거나 (”’) 큰따옴표를 세 번 연속으로 사용하는 방법(“””)입니다. 이 방식은 여러 줄로 구성된 문자열을 입력할때 편리합니다. 예를 들어 아래와 같은 일반적인 문자열이 있다고 가정하겠습니다.

The quick brown fox
jumps over
the lazy dog

C에서 이 문자열을 그대로 입력하려면 이 텍스트를 복사해서 붙여놓고 줄바꿈 부분을 없애고 줄이 바뀌는 부분을 모두 줄바꿈 기호(\n)을 삽입해야 했습니다. 아래처럼요.

"The quick brown fox \njumps over \nthe lazy dog"

예제는 단지 세 줄이라 괜찮지만 50줄 100줄짜리 문자열을 이렇게 처리하려면 정말 번거롭습니다. 파이썬에서는 이를 ”’ 혹은 “”” 으로 간편하게 입력할 수 있습니다.

"""
The quick brown fox
jumps over
the lazy dog
"""

 

파이썬 문자열 다루기

시퀀스 연산(Sequence Operation)

자, 이제 문자열을 어떻게 하면 자유자재로 다룰 수 있는지 알아봅시다. 몇 가지 예제 코드를 보겠습니다.

>>> s = 'Luke Skywalker'
>>> s[0]
'L'
>>> s[0:3]
'Luke'

첫 번째 코드 s[0]은 문자열 s 의 값 중 첫 번째 값을 가져오라는 연산입니다. 따라서 파이썬은 문자열 ‘Luke Skywalker’ 의 첫 번째 글자인 ‘L’을 보여줍니다. 두 번째 코드 s[0:3]은 문자열 s의 값 중 1~4번째 값을 가져오라는 연산입니다. 역시 파이썬은 1~4번째 글자인 ‘Luke’를 반환하죠.

그렇습니다. 문자열은 사람에게는 그저 문자열이지만 파이썬은 문자열 글자 하나하나마다 순서를 매겨 관리하고 있습니다. 비단 문자열 뿐만 아니라 뒤에 설명할 자료형인 리스트, 튜플도 이와 같이 요소 하나하나마다 순서를 매겨서 관리합니다. 이를 시퀀스(Sequence) 자료형이라 합니다.

문 자열 얘기하다가 시퀀스 자료형 얘기하니까 헷갈리시죠? 사실 저도 문자열만 설명할까 하다가 문자열을 다루는 연산 중 많은 수가 시퀀스 자료형을 다루는 시퀀스 연산(Sequence Operations)이며, 이는 리스트와 튜플에도 그대로 적용되기 때문에 지금 설명했습니다.

시퀀스 연산- 문자열 인덱싱

인덱싱(Indexing)이란 어떤 것을 가리키는 것을 말합니다. 아래 코드를 보면서 설명하겠습니다.

>>> s = 'Darth Vader'
>>> s[0]
'D'
>>> s[1]
'a' 

아! 낯익은 코드군요. 위에서 한 번 설명했던 코드입니다. 첫 번째 명령어는 문자열의 첫 번째 아이템을 가져오라는 연산입니다. 두 번째 명령어는 문자열의 두 번째 아이템을 가져오라는 연산이죠. 파이썬의 시퀀스 자료형에 ‘[숫자]’를 붙이면 해당 숫자의 아이템을 가져오라는 연산입니다. 이를 인덱싱 연산이라고 합니다.

주의
거의 모든 컴퓨터 프로그래밍 언어에서 그렇듯, 파이썬에서 수의 시작은 1이 아니라 0입니다.
>>> s[-1]
'r'
>>> s[-2]
'e'

그 런데 위의 코드는 뭘까요? 인덱스가 -1, -2 입니다. 프로그래밍 경험이 있으신 분들은 당황하실지도 모르겠습니다. C/C++, Java 에서는 이런 인덱싱 연산에 음수가 오면 에러가 발생하거나 컴파일이 안되거든요. 하지만 -1이니까 뭔가 뒤에서 부터 세지 않을까? 라고 직관적으로 생각하신 분들은 바로 정답! 입니다. 음수가 붙으면 문자열의 뒤에서부터 순서를 세기 때문에 -1은 맨 뒤의 ‘r’ 문자를, -2는 뒤에서 두 번째 문자인 ‘e’를 가리킵니다.

시퀀스 연산 – 문자열 슬라이싱

마 트에 가면 “슬라이스 치즈”(Slice Cheese)를 살 수 있습니다. 원래 치즈는 덩어리인데 이를 얇게 잘라서 먹기 편하게 만든 치즈가 바로 “슬라이스 치즈”입니다. 파이썬에서도 이런 시퀀스 자료형을 일부만 잘라서 쓸 수 있습니다. 슬라이싱(Slicing)이라고 합니다.

예를 들어 요런거?

예제 코드를 볼까요?

>>> s = 'Darth Vader'
>>> s [0:3]
'Dar'

시퀀스 슬라이싱 연산의 일반적인 형태는 X[start:end] 형태입니다. 이는 곧 “문자열 X의 start번째 아이템부터 end-1 번째 아이템까지 넘겨주세요.”라는 뜻입니다. start부터 end번 째 아이템까지 넘겨 줘야하는게 아닌가 하고 반문하시는 분들을 위해 아래 그림을 그렸습니다. 첫 번째 연산 s[0:3]을 예로 들겠습니다. 이 연산은 문자열 s의 0번째부터 3-1번째 아이템까지 선택합니다. 따라서 문자열 ‘Dar’가 반환됩니다.

sequence

위 그림에서 0부터 3번째 인덱스까지 선택하면 0,1,2번째 아이템은 선택되지만 3번째 아이템은 선택되지 않는다는 것을 알 수 있습니다.

슬라이싱 연산의 일반적인 형태는 X[start:end]지만, start 혹은 end 를 생략할 수 있으며, 심지어 start와 end 모두 생략할 수 있습니다. start가 생략되면 처음부터, 즉 0과 마찬가지이며, end가 생략되면 끝까지 다 선택한다는 의미입니다.

>>> s[:3] # s[0:3] 과 같습니다.
'Dar'
>>> s[3:] # 3번째 아이템부터 끝까지 반환합니다. 3번째 아이템이라는 것은 실제로 4번째 글자부터입니다.
'th Vader'
>>> s[:-2] # 처음부터 끝에서 두 번째 아이템까지 반환합니다. 끝에서 두 번째 아이템은 반환하지 않습니다.
'Darth Vad'
>>> s[:] # 처음부터 끝까지 반환합니다.
'Darth Vader'

시퀀스 자료형 슬라이싱 하나 더! – 스텝(step)

파이썬 2.3부터 슬라이싱 방법에 작은 변화가 생겼습니다. 바로 스텝(Step)입니다. 시퀀스 자료형의 슬라이싱 연산의 일반적인 형태는 X[start:end]라고 했습니다. 이에 덧붙여 몇 단계를 결정할지 정하는 step 방식이 도입되었습니다. 이를 확장 슬라이스(extended slice)라고 하는데요, 이 확장 슬라이스의 형태는 X[start:end:step] 형태를 가집니다. 예를 들어 문자열의 짝수 번째 문자열만 가져오고 싶다면 아래와 같이 사용하면 됩니다.

>>> s = 'abcdefghijk'
>>> s[1::2] # 첫 번째부터 끝까지
'bdfhj'

시퀀스 자료형 더하기, 반복

파이썬에서는 시퀀스 자료형을 간단하게 간단하게 붙일 수 있습니다. 예를 들어 두 개의 문자열을 붙이고 싶다면 C에서는 아래와 같이 코드를 작성해야 합니다.

#include <string.h>
/* ... */
char str[20];
const char* s1 = "Jang";
const char* s2 = "Yes";
/* strncat(), strncpy()를 써야 안전하지만 예제라 그냥 사용합니다.*/
strcpy (str, s1);
strcat (str, s2);

참으로 번잡하죠? 파이썬에서는 이를 + 연산자로 직관적으로 붙일 수 있습니다.

>>> s1 = 'Jang'
>>> s2 = 'Yes'
>>> s = s1 + s2
>>> s
'JangYes'

또한 같은 문자열을 반복할 수도 있습니다.

>>> s1 = "Yes"
>>> s = s1 * 3
>>> s
'YesYesYes'

몇 가지 시퀀스 연산이 더 있지만, 이 다음 섹션인 리스트나 튜플에서 마저 다루도록 하겠습니다. 여기까지는 시퀀스 자료형에 대한 설명이었습니다. 위에서 설명한 연산은 문자열 뿐만 아니라 다음 섹션인 리스트나 튜플에서도 똑같이 적용되니 잘 알아두시기 바랍니다.

파이썬 문자열 전용 연산

불변의 문자열

문자열 고유의 연산 소개에 앞서, 문자열의 특징을 짚고 넘어가려 합니다. 문자열은 한 번 선언되면 수정을 할 수 없다는 특징이 있습니다. 이를 문자열의 불변성(Immutability)이라고 합니다.

>>> s = 'Amidala'
>>> s[0] = 'P'

위 예제는 문자열을 변수 s에 넣고 s의 첫 번째 아이템을 수정하려고 시도합니다. 이 경우 파이썬에서 에러를 발생합니다. 만약 해당 문자열을 수정하고 싶다면 새로운 객체를 만들어서 복사하는 방식을 사용해야 합니다.

>>> new_str = 'P' + s[1:]

파이썬 문자열 찾기 find(), rfind()

문자열에서 특정 문자열을 찾을 때 사용합니다. 사용법은 find(찾을 문자열, 검색 시작 index, 검색 끝 index) 입니다. 이 중 두, 세 번째 인자를 생략하면 전체 문자열 중 검색을 하게 되며, 세 번째 인자를 생략하면 문자열의 특정 인덱스부터 시작해서 끝까지 검색합니다.

>>> s = 'Anakin Skywalker : you underestimate my power!'
>>> s.find('under') #23번째 인덱스에서 'under' 를 찾았습니다.
23
>>> s.find('Darth Vader') #'Darth Vader' 를 못 찾으면 -1을 반환합니다.
-1
>>> s.find('power', 3) # 3번째 인덱스부터 'power' 문자열을 찾습니다.
40
>>> s.find('power', 3, -10) # 3번째 인덱스부터 끝에서부터 10번째 앞의 문자열까지 검색합니다.
-1

find() 가 문자열의 앞에서 부터 검색을 한다면, rfind()는 뒤에서 부터 문자열을 검색합니다. 사용법은 find()와 같습니다. 어떤 문자열의 뒤부터 특정 문자열을 검색하고자 할때 유용합니다.

>>> s = 'What do you do?'
>>> s.rfind('do') #뒤에 위치한 'do' 의 위치를 반환합니다
12
>>> s.find('do') #앞에 위치한 'do'의 위치를 반환합니다.
5

파이썬 문자열 교체 replace()

문자열 내 특정 문자열을 다른 문자열로 치환합니다. replace(변경할 대상 문자열, 변경할 문자열, 변경 횟수 제한) 로 사용합니다. 세 번째 인자는 생략 가능합니다.

>>> s = 'Anakin Skywalker'
>>> s.replace('Anakin', 'Luke')
'Luke Skywalker'

파이썬 문자열 쪼개기 split()

특정 패턴을 가진 문자열을 잘라냅니다. 흔히 토크나이징(Tokenizing) 한다고 합니다. 사용법은 split(구분기호, 횟수 제한)입니다. 모든 인자가 생략 가능한데, 첫 번째 인자가 생략되면 빈칸을 기준으로 문자열을 쪼갭니다. 결과로는 쪼개진 문자열 리스트를 반환합니다.

>>> s = 'a,b,c,d,e'
>>> s.split(',') # 콤마(,)를 구분기호 삼아 문자열을 쪼갭니다.
['a', 'b', 'c', 'd', 'e']
>>> s.split() # 빈칸을 구분기호 삼아 문자열을 쪼갭니다.
['a,b,c,d,e']
>>> s = 'a b c d e'
>>> s.split()
['a', 'b', 'c', 'd', 'e']

문자열 좌우를 깔끔하게 strip(), rstrip(), lstrip()

문자열 좌우에 있는 공백 및 기타 문자를 제거하고자 할 때 사용합니다. 사용법은 strip(제거할 문자열)입니다. 인자는 생략 가능한데, 생략되면 기본적으로 빈칸(whitespace)만 제거합니다.

>>> s = '   www.shiftnegative.com   '
>>> s.split()  # 좌우 공백만 제거합니다.
'www.shiftnegative.com'
>>> s.split('cmow. ') # 좌우 c,m,o,w,.,공백을 제거합니다.
'shiftnegative' 

rstrip()과 lstrip()도 strip()과 사용법이 같습니다. 다만 rstrip()은 문자열 오른쪽, lstrip()은 문자열 왼쪽의 공백 및 기타 문자를 제거할 때 사용합니다.

처음 글자가 무엇으로 시작하나요? 마지막 글자가 무엇으로 끝나나요? startswith(), endswith()

startswith()는 문자열의 처음이 어떤 문자로 시작하는지, endswith()는 어떤 문자로 끝나는지 파악할 때 사용합니다. 간단한 함수지만 의외로 많이 사용합니다.

>>> s = 'Good relations with the Wookies, I have. '
>>> s.startswith('G')
True
>>> s.endswith('.')
True
>>> s.startswith('A')
False

맞으면 Boolean 데이터형인 True, 틀리면 False 를 리턴합니다. Boolean 형은 추후 설명하겠습니다.

유니코드, Raw string 그리고 한글(작성 중)

 

참고자료

  1. 파이썬 공식 문서 5. Built-in Type

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *