파이썬 기초 강좌 #7 문자열 다루기
파이썬 기초강좌 일곱번째 강좌인 문자열 다루기를 시작하겠습니다.
문자열이란?
영어로 string이라고 불리는 문자열은 캐릭터(character)의 나열입니다. 문자열은 홀 따옴표나 쌍 따옴표를 사용하여 표시하며('string' 또는 "string"), 플러스(+) 오퍼레이터를 사용하여 문자열끼리 결합할 수도 있습니다('schoolofweb' + '.net'). 실제 코드를 실행하면서 설명하겠습니다.
>>> 'string'
'string'
>>> "string"
'string'문자열 안에 홀 따옴표나 쌍 따옴표를 표시해야 할 경우가 있습니다. 보기와 같은 코드를 실행하면 신텍스 에러가 발생하게 됩니다.
>>> 'I'm a programmer'
File "<stdin>", line 1
'I'm a programmer'
^
SyntaxError: invalid syntax홀 따옴표를 표시하고 싶을 때는 쌍 따옴표로, 쌍 따옴표를 표시하고 싶을 때는 홀 따옴표로 문자열을 감싸면 됩니다.
>>> "I'm a programmer"
"I'm a programmer"
>>> 'He says "Hello!"'
'He says "Hello!"'또 다른 방법은 백슬래쉬를 사용하여 특수문자를 일반 문자로 예외 처리를 하는 방법이 있습니다. 위에서 에러가 났던 코드를 수정하여 실행해 보겠습니다.
>>> 'I\\'m a programmer'
"I'm a programmer"이번에는 에러 없이 잘 출력되는 것을 볼 수 있습니다.
문자열과 문자열을 결합하고자 할 때는 플러스 오퍼레이터를 사용하시면 됩니다.
>>> 'schoolofweb' + '.' + 'net'
'schoolofweb.net'하지만 문자열과 숫자를 합치려면 숫자를 먼저 문자열로 변환하여야 합니다. age라는 변수안의 숫자와 문자열을 결합해보겠습니다.
>>> 'I am ' + 18 + ' years old'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate str (not "int") to str타입 에러가 발생하는것을 볼 수 있습니다.
이번에는 문자열로 변환한 후 결합해 보겠습니다.
>>> 'I am ' + str(18) + ' years old'
'I am 18 years old'문제없이 결합되는 것을 볼 수 있습니다.
인덱싱이란?
인덱싱이란 브라켓 신텍스와 숫자를 사용하여 문자열안의 특정 위치의 문자를 추출하는 것을 말합니다. 파이썬은 0부터 시작하는 제로 베이스 인덱싱을 사용합니다. 제로 베이스 인덱스란 인덱스의 시작이 제로부터 시작하는 시스템입니다. 즉 첫 번째 아이템의 인덱스가 0가 되고 두번째 아이템이 1, 세번째 아이템이 2가 되는것을 말합니다.

마지막 아이템으로부터 인덱싱을 하는 것을 리버스 인덱싱이라고하고 이때 인덱스는 -1로부터 시작하여 1씩 감소하게 됩니다.
STRING 이라는 문자열을 변수에 저장한 뒤, 인덱스를 사용하여 첫 번째 문자인 S를 출력해 보겠습니다.
>>> var = 'STRING'
>>> var[0]
'S'이 번에는 리버스 인덱스를 사용하여 마지막 문자인 “G"를 출력해 보겠습니다.
>>> var[-1]
'G'이 문자열의 인덱스 레인지는 0부터 5까지입니다. 하지만 이 레인지를 벗어난 인덱스를 사용하면 인덱스 에러가 발생하게 됩니다.
앞에서 파이썬은 제로 베이스 인덱스를 사용한다고 설명을 드렸는데요, 사실상 C++, Java, JavaScript 등 거의 대부분의 주류 프로그래밍 언어가 제로 베이스 인덱스를 사용하고 있습니다. 하지만 Lua, Julia, R과 같이 언어들은 인덱스가 1로 시작되는 원 베이스 인덱스를 사용하고 있습니다.
이번에는 슬라이싱을 배워보도록 하겠습니다.
슬라이싱이란?
슬라이싱은 인덱스와 같이 브라켓 신텍스를 사용하여 문자열안에서 문자나 문자열을 추출하는 기술입니다. 인덱싱으로는 하나의 문자만을 추출할 수 있지만, 슬라이싱을 사용하면 여러개의 문자를 추출할 수 있습니다.
슬라이싱의 신텍스는 브라켓안에 세가지 숫자를 가집니다. 숫자와 숫자 사이는 콜론으로 구분합니다.
슬라이싱 신텍스
[start:stop:step]
start는 추출하고자 하는 문자열의 첫 캐릭터의 인덱스입니다. stop은 추출하고자 하는 문자열의 마지막 캐릭터의 인덱스에 1을 더한 값입니다. step은 start에서 stop까지의 증가 크기를 뜻합니다. step은 생략이 가능하며, 생략시에는 디폴트 값인 1이 사용됩니다. 만약 보기의 문자열에서 첫 3개의 캐릭터를 추출하고자 하면 [:3] 를 입력하면 됩니다.
>>> var[0:3]
'STR'이때 start 인덱스가 0이면 생략이 가능합니다.
>>> var[:3]
'STR'마지막 3개의 캐릭터를 추출하고 싶다면 [-3:] 를 입력하면 됩니다.
>>> var[-3:]
'ING'중간의 2개 캐릭터를 추출하고 싶다면 [2:4]를 사용하거나 [-4:-2]를 사용하시면 됩니다.
>>> var[2:4]
'RI'
>>> var[-4:-2]
'RI'이번에는 숫자와 알파벳이 섞인 문자열에서 step 값을 적용하여 알파벳만을 추출해 보겠습니다.
>>> mixed = '1a2b3c'
>>> mixed[1::2]
'abc'이번에는 스트링 빌트인 클래스가 제공하는 메소드에 대해서 알아보겠습니다.
str의 메소드
파이썬 안의 모든 것은 어떤 클래스의 오브젝트이며, 클래스 안에 정의된 메소드를 사용할 수 있습니다. 스트링 클래스도 다양하고 편리한 메소드를 제공합니다. 대표적인 것들은 다음과 같습니다.
upper: 문자열을 대문자로 변환lower: 문자열을 소문자로 변환capitalize: 첫 캐릭터를 대문자로 변환split: 문자열을 리스트 아이템으로 분리join: 특정 캐릭터나 문자열로 다른 문자를 연결strip: White space를 삭제replace: 특정 캐릭터를 다른 캐릭터로 치환format: 문자열 안의 플레이스홀더에 원하는 값을 대입
이중에서 일반적으로 많이 사용되는 메소드를 사용해보겠습니다.
먼저 한 문장을 변수에 저장하고, 타입 함수를 사용하여 변수에 저장된 오브젝트의 타입을 알아보겠습니다.
>>> greeting = 'welcome to schoolofweb.net.'
>>> type(greeting)
<class 'str'>string 오브젝트가 저장된것을 확인하였습니다.
dir 함수를 사용하여 스트링 오브젝트가 어떤 메소드를 사용할 수 있는지 출력해 보겠습니다.
>>> dir(greeting)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']Ipython이나 jupyter notebook을 사용하고 계시다면 탭키를 사용하여 코드 힌트를 볼 수도 있습니다.

첫 번째 캐릭터를 대문자로 변환해주는 capitalize 메소드를 실행해 보겠습니다.
>>> greeting.capitalize()
'Welcome to schoolofweb.net.'이번에는 모든 문자열을 대문자로 변환하는 upper 메소드와 모든 문자열을 소문자로 변환하는 lower 메소드를 실행해보겠습니다.
>>> greeting.upper()
'WELCOME TO SCHOOLOFWEB.NET.'
>>> greeting.lower()
'welcome to schoolofweb.net.'이번에는 특정 문자를 이용하여 문자와 문자를 연결해 주는 join 메소드를 사용해 보겠습니다.
>>> period = '.'
>>> abc = 'ABC'
>>> period.join(abc)
'A.B.C'ABC 문자열의 각 캐릭터가 피리어드로 연결된 것을 볼 수 있습니다.
이 번에는 양 사이드의 white space를 삭제하는 strip 메소드를 사용해 보겠습니다.
>>> spaces = ' strip example '
>>> spaces.strip()
'strip example'양 사이드의 white space가 삭제된 것을 볼 수 있습니다.
다음의 문자열을 콤마를 기준으로 하여 스플릿하여보겠습니다.
>>> numbers = 'one,two,three,four,five'
>>> numbers.split(',')
['one', 'two', 'three', 'four', 'five']콤마를 기준으로 각 단어가 리스트 아이템으로 분리된것을 볼 수 있습니다.
이 번에는 특정 캐릭터나 문자열을 치환하는 replace 메소드를 사용해보겠습니다.
>>> foo = 'this is a java tutorial for java programmers'
>>> foo.replace('java', 'python')
'this is a python tutorial for python programmers'java 라는 문자열이 python으로 치환된것을 볼 수 있습니다.
String Formatting
빈 컬리 브레이스 사용
'My name is {}. I am {} years old.'.format(name, age)키워드 사용
'My name is {name}. I am {age} years old.'.format(name=name, age=age)인덱스 사용
'My name is {1}. I am {0} years old.'.format(age, name)마지막으로 확인할 메소드는 format 메소드입니다. 포멧 메소드를 사용하면 문자열안에 컬리브레이스로 여러개의 플레이스 홀더를 정의한 뒤 원하는 값으로 다이나믹하게 치환할 수 있습니다. 즉 템플릿을 만들어 사용한다고 생각하시면 됩니다. 포멧 메소드를 사용하려면 문자열 안에 컬리 브레이스를 사용하여 플레이스 홀더를 정의합니다. 이 플레이스 홀더의 사용 방법은 세가지가 있습니다. 첫 번째 방법은 빈 컬리브레이스를 사용하는 방법입니다. 빈 컬리 브레이스를 사용하면 format 메소드에 전달되는 인자가 플레이스 홀더에 순서대로 치환됩니다.
>>> name = 'Pink'
>>> age = 13
>>> 'My dog\\'s name is {}. She is {} years old.'.format(name, age)
"My dog's name is Pink. She is 13 years old."플레이스 홀더의 숫자와 메소드에 전달되는 인자의 수는 꼭 같아야 하며, 만약 수가 매칭되지 않으면 인덱스 에러가 발생합니다. 이 예와 같이 플레이스 홀더는 2개인데 인자를 하나만 패스하면 인덱스 에러가 발생합니다.
>>> 'My dog\\'s name is {}. She is {} years old.'.format(name)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: Replacement index 1 out of range for positional args tuple두번째 방법으로는 키워드를 사용하는 방법이 있습니다. 플레이스 홀더가 많고 같은 값을 여러 번 사용하는 경우에는 키워드를 사용하는 것을 권장합니다.
>>> 'My dog\\'s name is {name}. She is {age} years old.'.format(name=name, age=age)
"My dog's name is Pink. She is 13 years old."세번째 방법은 인덱스를 사용하는 방법입니다. 컬리 브레이안에 format 메소드에 전달 되는 인자의 인덱스를 입력하면 됩니다.
>>> 'My dog\\'s name is {1}. She is {0} years old.'.format(age, name)
"My dog's name is Pink. She is 13 years old."다음과 같이 숫자 앞에 제로 패딩을 표시할 수도 있습니다.
>>> for i in range(1, 11):
... print('file_{:03d}'.format(i))
...
file_001
file_002
file_003
file_004
file_005
file_006
file_007
file_008
file_009
file_010여기서 제로는 빈 공간을 제로 캐릭터로 채우겠다는 뜻이고, 3은 문자열의 최소 길이를 뜻합니다.
포맷 메소드를 사용하면 소수점 자릿수를 정의할 수도 있습니다. 소수점 셋째 자리만 출력해 보겠습니다.
>>> '{:.3f}'.format(1.55555)
'1.556'뒤에 소수점을 버리면 반올림 또는 반내림을 하는 것을 기억하시기 바랍니다.
로그 등을 출력할 때 문자 길이를 맞추거나 왼쪽, 중앙, 오른쪽 정렬 등을 하여 보기좋게 포멧팅할 수도 있습니다.
>>> text = ''
>>> text += '{:10s} {:9s} {:4s}\\n'.format('First Name', 'Last Name', 'Age')
>>> text += '{} {} {}\\n'.format('-'*10, '-'*9, '-'*4)
>>> for person in people:
... text += '{:>10s} {:^9s} {:<4d}\\n'.format(person['firstname'], person['lastname'], person['age'])
...
>>> print(text.strip())
First Name Last Name Age
---------- --------- ----
John Doe 30
Jane Doe 29
Curtis Lee 43이번 강좌는 여기서 마치고 다음 강좌에서는 리스트에 대해서 알아보겠습니다.