[데이터과학을위한파이썬프로그래밍] 문자열
Chapter 06 문자열
01. 문자열의 이해
[1] 문자열의 개념
문자열 string은 애플리케이션을 만들거나 데이터를 분석할 때, 매우 중요하게 다루는 자료형 중 하나이다.
문자열을 이해하기 위해서는 문자열의 특징을 이해해야 한다. 먼저 문자열은 시퀀스 자료형 sequence data type 이다. 시퀀스 자료형은 리스트와 같이 데이터를 순차적으로 메모리에 저장하는 형식의 데이터이다.
[2] 문자열과 메모리 공간
일반적으로 문자열을 저장하기 위해서는 영문자 한 글자당 1바이트의 메모리 공간을 사용한다. …
[3] 문자열의 인덱싱
앞서 문자열은 시퀀스 자료형이라고 설명하였다. 시퀀스 자료형은 리스트와 특징이 거의 같은 자료형이라고 생각하면 된다.
따라서 문자열의 특징 중 하나가 바로 인덱싱 Indexing이다. 리스트처럼 글자 하나하나가 상대적인 주소 offset를 가지는데, 이 주소를 사용해 할당된 값을 가져오는 인덱싱을 사용할 수 있다.
#실제 코드에서는 다음과 같이 작성할 수 있다.
>>> a = "abcde"
>>> print(a[0], a[4]) #a 변수의 0번째, 4번째 주소에 있는 값
ae
>>> print(a[-1], a[-5]) # 변수의 오른쪽에서 10번째, 4번째 주소에 있는 값
ea
예를들어, 변수 a에 값 abcde가 있을 때 a[0], 즉 의 0번째 값은 a로 출력된다. 마찬가지로 a의 4번째 값은 e로 출력되는 것을 확인할 수 있다. 역순으로 인덱싱을 할 수도 있다. 왼쪽부터 -1로 시작하여 -5까지 주소가 변하는 것을 확인할 수 있다
[4] 문자열의 슬라이싱
슬라이싱 slicing은 문자열의 주소값을 기반으로 문자열의 부분값을 반환하는 기법이다. (이미 리스트에서 살펴본 내용이다. )
>>> a = "TEAMLAB MOOC, AWESOME Python"
>>> print(a[0:6], "AND ", a[-9:]) # 변수의 부터 5까지 9부터 끝까지
TEAMLA AND ME Python
>>> print(a[:]) # 변수의 처음부터 끝까지
TEAMLAB MOOC, AWESOME Python
>>> print(a[-50:50]) # 범위를 넘어갈 경우 자동으로 최대 범위를 지정
TEAMLAB MOOC, AWESOME Python
>>> print(a[::2], "AND ", a[::-1])
TALBMO,AEOEP to AND nohtyP EMOSEWA ,COOM BALMAET
[5] 문자열의 연산
문자열도 일반적인 변수와 마찬가지로 연산을 지원한다. 가장 기본적인 연산은 리스트의 연산과 같다. 예를 들어, 문자열 변수와 정수형인 2의 '2+2'와 같은 연산은 동작하지 않는다.
하지만 'a*2'와 같은 연산은 지원한다. 다음 코드를 살펴보자.
>>> a = "TEAM"
>>> b = "LAB"
>>> print(a + "" + b) #덧셈으로 a와 b 변수 연결하기
TEAM LAB
덧셈 연산은 모든 변수가 문자열이라면 텍스트 붙이기 concatenate를 실행한다.
>>> print(a*2 + "" + b*2) #곱하기로 반복 연산 가능
TEAMTEAM LABLAB
a * 2를 풀면 a + a의 연산이므로, 같은 글자가 두 번 출력되는 것을 확인할 수 있다.
>>> if 'A' in a: print(a) #'A'가 a에 포함되었는지 확인
else:print(b)
---
TEAM
흔히 if문과 함께 사용하는데, 특정 문자가 특정 변수에 들어가 있는지 확인하는 연산
자주 하는 실수 중 하나가 print() 함수에서 정수형과 문자열을 같이 보여 주려고 할 때 발생한다.
#문자열과 정수형의 연산으로 인식하여 덧셈 연산이 실행되지 않는다.
>>> int_value = 2
>>> print("결과는" + int_value)
[6] 문자열 함수
함수명 | 기능 |
len() | 문자열의 문자 개수를 반환 |
upper() | 대문자로 변환 |
lower() | 소문자로 변환 |
title() | 각 단어의 앞글자만 대문자로 변환 |
capitalize() | 첫 문자를 대문자로 변환 |
count(찾을 문자열) | 찾을 문자열이 몇 개 들어 있는지 개수 반환 |
find(찾을 문자열) | 찾을 문자열이 왼쪽 끝부터 시작하여 몇 번째에 있는지 반환 |
find(찾을 문자열) | find() 함수와 반대로 찾을 문자열이 오른쪽 끝부터 시작하여 몇 번째에 있는지 반환 |
startswith(찾을 문자열) | 찾을 문자열로 시작하는지 여부 반환 |
endswith(찾을 문자열) | 찾을 문자열로 끝나는지 여부 반환 |
strip() | 좌우 공백 삭제 |
rstrip() | 오른쪽 공백 삭제 |
Istrip() | 왼쪽 공백 삭제 |
split() | 문자열을 공백이나 다른 문자로 나누어 리스트로 반환 |
isdigit() | 문자열이 숫자인지 여부 반환 |
islower() | 문자열이 소문자인지 여부 반환 |
isupper() | 문자열이 대문자인지 여부 반환 |
>>> title = "TEAMLAB X Inflearn"
>>> title.title()
'Teamlab X Inflearn'
>>> title.capitalize()
'Teamlab X inflearn'
>>> title.count("a") #title 변수에 'a'가 몇 개 있는지 개수 반환
1
>>> title.upper().count("a") # title 변수를 대문자로 만든 후, 'a'가 몇 개 있는지 개수 반환
0
>>> title.isdigit() #title 변수의 문자열이 숫자인지 여부 반환
False
>>> title.startswith("a") #title 변수가 'a'로 시작하는지 여부 반환
False
02. Lab: 단어 카운팅
: <Yesterday>라는 노래에서 'Yesterday'라는 단어가 몇 번 나오는지 맞히는 단어 카운팅 프로그램
f = open("yesterday.txt", 'r')
yesterday_lyric = f.readlines()
f.close()
contents = " "
for line in yesterday_lyric:
contents=contents + line.strip() + "\\n"
n_of_yesterday = contents.upper().count("YESTERDAY")
print("Number = of 'Yesterday'", n_of_yesterday)
- 1~3행에서 'yesterday.txt 파일에서 모든 내용을 불러와 yesterday_lyric 리스트로 저장
- 5~7행에서 for문을 사용하여 yesterday_lyric 리스트의 내용을 한 줄씩 불러오면서 contents 변수에 저장한다. 그러면 contents 변수에는 〈yesterday> 노래의 모든 가사가 저장된다.
- 9~10행에서 contents 변수에 있는 값은 모두 대문자로 바꾸는 upper() 함수를 사용하여 대문자로 변환한 후, count() 함수를 사용하여 대문자 ‘YESTERDAY'가 몇 개인지를 확인한다.
- contents.upper().count("YESTERDAY") 함수를 붙여 써도 작동하는 이유는 upper() 함수의 경우 contents 변수에 값 자체를 변경하는 것이 아니라, 변경된 값을 반환해주는 함수일 뿐이기 때문
- *이렇게 해도 똑같이 나옴
- #upper() 함수 >>> title = "teamlab" >>> title 'teamlab' >>> title.upper() 'TEAMLAB' >>>> title 'teamlab'
- *이렇게 해도 똑같이 나옴
- contents = "" for line in yesterday_lyric: contents =contents+line #2 print(contents) n_of_yesterday = contents.upper().count("YESTERDAY") print("number_of_yesterday : ", n_of_yesterday) f.close()
03. 문자열 서식 지정
: 문자열의 형식을 정하여 출력하는 서식 지정
: print()함수를 사용하여 형식을 통일한 문자열을 출력할 때 유용
[1]서식 지정의 개념
print() 함수는 기본적으로 변수 또는 값을 콤마(,)로 띄어쓰기하여 출력한다. 하지만 print() 함수를 사용하다 보면 어떤 형식에 맞추어 결과를 출력해야 할 일이 발생하기도 한다.
특히 엑셀을 사용할 때 통화 단위, 세 자리 숫자 단위 띄어쓰기, % 출력 등 다양한 형식에 맞추어 출력할 일이 생기는데,
이를 서식 지정 formatting이라고 한다. 출력 형식을 맞추기 위하여 문자열을 print() 함수와 함께 어떻게 사용하는지 알아보자.
[2] % 서식과 format() 함수
: 문자열의 서식 format 을 설정할 때, print()함수는 기본적인 출력 형식 외에 % 서식과 format() 함수를 구문으로 사용하여 출력 양식을 지정할 수 있다.
#별도의 서식 지정 없이 그대로 print() 함수를 사용
print(1,2,3)
print("a" +"" + "b"+" " + "C")
#% 서식 지정과 format() 함수를 사용
print("%d %d %d" % (1, 2, 3))
print("{}{}{}".format("a", "b", "c"))
123 abc 123 abc
이런 식으로 서식을 지정하여 출력하면 어떤 장점이 있을까?
첫째, 데이터와 출력 형식을 분류할 수 있다.
같은 내용을 여러 번 출력하기 위해 기존 print()문 에 띄어쓰기를 넣어 + 기호로 문자열 형태를 붙여 주는 것보다 시각적으로 훨씬 이해하기 쉽게 코드를 표현할 수 있다.
둘째, 데이터를 형식에 따라 다르게 표현할 수 있다.
: 문자열 형태인 (one', 'two') 구문과 정수형인 (1, 2) 구문이 각각 %s %d로 다르게 할당
>>>print("%s %s' % ('one', 'two'))
one two
>>>print("%d %d % (1, 2))
1 2
서식 지정 기능은 각 변수의 자료형에 맞게 다른 서식으로 지정한다.
서식 지정은 %를 사용하는 방법과 문자열 형태의 format() 함수를 사용하는 방법이 각각 다 른데, 이에 대해 자세히 설명하겠다.
2.1% 서식
:: '% 자료형 % (값)’
print("I eat %d apples." % 3)
print("I eat %s apples." % "five")
I eat 3 apples.
I eat five apples.
#%는 1개 이상의 값도 할당할 수 있다.
#직접 값을 넣지 않고 number와 day 같은 변수명을 넣어도 문제없이 실행된다.
number = 3
day = "three"
print("I eat %d apples.I was sick for %s days." % (number, day))
I ate 3 apples. I was sick for three days
2.2 format() 함수
"[자료형}".format(인수)
: format()함수는 % 서식과 거의 같지만, 문자열 형태가 있는 함수를 사용한다는 차이점이 있다.
>>> print("I'm {0} years old.".format(20))
I'm 20 years old.
>>>age = 40; name = 'Sungchul Choi'
>>>print("I'm {0} years old.".format(age))
I'm 40 years old.
>>>print("My name is {0} and {1} years old.".format(name, age))
My name is Sungchul Choi and 40 years old.
>>>print("Product: {0}, Price per unit: {1:2f}.".format("Apple", 5.243))
Product: Apple, Price per unit: 5.24.
서식 | 설명 |
%s | 문자열(string) |
%c | 문자 1개(character) |
%d | 정수 (integer) |
%f | 실수 (floating-point) |
[3] 패딩
: 여유 공간을 지정하여 글자 배열을 맞추고 소수점 자릿수를 추는 패딩 padding 기능
: % 서식과 format() 함수 모두 패딩 기능을 제공한다.
3.1 % 서식의 패딩
#공간
>>> print("%10d"%12)
12
>>> print("%-10d" % 12)
12
#소수점
>>> print("%10.3f" %5.94343) #10 자리를 확보하고 소수점 셋째 자리까지 출력
5.943
>>> print("%10.2f" %5.94343)
5.94
>>> print("%-10.2f" %5.94343)
5.94
3.2 format() 함수의 패딩
#정렬
>>> print("{0:>10s}".format("Apple")) #우측정렬
Apple
>>> print("{0:<10s}".format("Apple")) #좌측정렬
Apple
#소수점
# 문자열 "Apple"은 인덱스 0에 해당하고, 숫자 5.243는 인덱스 1에 해당합니다.
# 하지만 format() 메서드에 전달된 숫자와 문자열 인덱스가 뒤바뀌어 있어서 올바른 결과를 얻을 수 없습니다.
"{1:10.5f}.".format("Apple", 5.243)
# 결과: ' 5.24300.' (5.243을 소수점 이하 다섯 자리까지 표시하고, 전체 너비가 10인 공간에 오른쪽 정렬)
"{1:>10.5f}.".format("Apple", 5.243)
# 결과: ' 5.24300.' (위와 같은 결과로 숫자와 문자열의 인덱스가 바뀌어 있어도 결과는 같음)
"{1:<10.5f}.".format("Apple", 5.243)
# 결과: '5.24300 ' (5.243을 소수점 이하 다섯 자리까지 표시하고, 전체 너비가 10인 공간에 왼쪽 정렬)
# 숫자와 문자열의 인덱스가 뒤바뀌었으므로 "Apple"은 무시되고, 숫자만 포맷팅되어 출력됩니다.