일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- database
- geometry
- 코딩테스트
- greedy
- string
- 구현
- bit manipulation
- Counting
- Tree
- 자바
- Binary Search
- array
- Number Theory
- sorting
- Stack
- dynamic programming
- Class
- 파이썬
- simulation
- java
- SQL
- 코테
- two pointers
- Binary Tree
- Data Structure
- Matrix
- Method
- Math
- implement
- hash table
- Today
- Total
코린이의 소소한 공부노트
데이터 타입, 연산자 (2) 문자열형 본문
문자열형을 둘러보기 전에 OX퀴즈 두 문제를 내보겠다.
- 변수를 확인할 때 타입만 확인하는 방법은 없다.
- 변수를 선언함과 동시에 반드시 값을 할당해줘야 한다.
(학교에서 시험 볼 때를 생각해보면, 답을 잘 모르겠을 때 '~만' 또는 '반드시'가 들어간 보기는 틀린 보기라는 게 너무 티가 나네ㅋㅋ 했었는데.. 막상 내가 내보니 그렇게 되는구나..ㅎ)
답은 X, X이다!
- 변수나 값의 타입이 궁금하다면 type함수를 쓰자.
a = 1.1
type(a)
>> float
type(1)
>> int
위에서 보듯 변수의 타입을 물어볼 수도 있고, 직접 값을 넣어 해당 값의 타입도 알 수 있다.
- 변수를 선언할 때 어떤 값을 할당해줘야 할지 아직 모르겠을 때, 혹은 변수 선언만 해놓고 나중에 값을 할당하고 싶을 때는 None을 쓰자.
not_yet = None
print(type(not_yet))
>> <class 'NoneType'>
print(not_yet)
>> None
not_yet에 None을 할당하니 NoneType이라고 나온다. (클래스는 차차 알아가보자.) 변수 선언 시 아무것도 넣지 않아서 아무것도 아닌 타입이라는 타입(?)이 된 것이다. 출력해봐도 None으로만 나온다.
타입에 대한 소소한 궁금증도 풀어봤으니, 숫자형, 논리형 데이터에 이어 문자열형에 대해 알아보겠다.
문자열부터는 내용이 많아서 글 하나에 한 타입만 소개하려 한다.
이번 글에서 알아볼 것은
1. 문자열형을 선언하는 방법
2. 특별한 문자열, 이스케이프 문자
3. 문자열에 번호가 있다?!
4. 문자열 연산이다.
1. 문자열형(String type) 선언
문자열은 말 그대로 문자들의 나열(조합)이다.
문자열이 아무것도 들어있지 않은 빈 문자열은 이렇게 나타낸다.
empty_str = ''
print(empty_str)
>> ''
문자열이 들어있는 일반적인 문자열은 이렇게 쓴다.
str_example1 = 'Mom said, "Call me."'
str_example2 = "Life's so cool!"
print(str_example1)
>> Mom said, "Call me."
print(str_example2)
>> Life's so cool!
작은따옴표, 큰 따옴표 상관없이 써도 무방하다.(당연히 짝은 맞춰서 써야지, 작은 거랑 큰 거랑 섞어서 쓰면 안 된다!)
단, 문자열 안에 작은따옴표를 쓰고 싶다면 큰 따옴표로 문자열을 감싸고, 큰 따옴표를 쓰고 싶다면 작은따옴표로 감싸야 에러가 발생하지 않는다.
str_example3 = '''여러 줄로도
가능합니다
'''
str_example4 = """
이것도
가능하지요!"""
print(str_example3)
>> 여러 줄로도
가능합니다
# 이 줄은 print의 결과!!
# 이 줄은 가독성을 위해 띄워둔 줄!
print(str_example4)
>>
이것도
가능하지요!
따옴표를 3개씩 겹쳐서 문자열을 감싸면 여러 줄로도 출력이 가능하다.
눈치를 챈 사람도 있겠지만, 따옴표를 문자열과 같은 줄에 쓰냐 다른 줄에 쓰냐에 따라서 엔터가 한 번 들어가는지 안 들어가는지도 차이가 있다.
2. 특별한 문자열, 이스케이프 문자(escape string)
문자열 선언을 보다 보면 이런 생각이 들 수 있다.
여러 줄을 쓰는 건 꼭 따옴표 3개로만 표현이 가능한 것인가? 답은 아니다!
이스케이프 문자(escape string)는 문자들 중에서 일부를 특정한 의미로 쓸 수 있게 만든 문자열이다.
이스케이프는 \(백슬래쉬 또는 원화)를 써서 문자에 의미를 부여해서 쓴다.
\n | 엔터(줄바꿈) | \t | 탭 | \b | 백스페이스 | \000 | 널(null) |
\\ | \ 자체 | \' | 작은따옴표 | \" | 큰따옴표 | ||
\r | 줄바꿈+커서 앞으로 이동 | \f | 줄바꿈+커서 다음으로 이동 | \a | 벨소리 | \v | 수직탭 |
색이 연한 것은 잘 안 쓰이는 거라고 들었다. 본인은 \n밖에 안 써봤기 때문에 나머지 이스케이프 문자들이 어떻게 나오나 궁금해서 한번 돌려보기로 했다.
print('python') # 일반 출력
>> python
print('\npython') # 줄바꿈(\n)
>>
python
print('\tpython') # 탭(\t)
>> python
print('python\b') # 백스페이스(\b)
>> pytho
일반 출력을 기준으로 보면 줄 바꿈은 한 줄 띄기, 탭은 한탭 띄기, 백스페이스는 \b 앞 문자 1개를 지우기를 하고 있음을 알 수 있다.
print('\000') # 널(\000)
>>
print('싸이버거 \\3,800') # \자체(\\), 글씨체에 따라 백슬래쉬 또는 원화로 나올것이다.
>> 싸이버거 \3,800
print('mom\'s touch') # 작은따옴표(\')
>> mom's touch
print('큰따옴표는 \"이거야!') # 큰따옴표(\")
>> 큰따옴표는 "이거야!
널(null)은 아무것도 들어있지 않은 빈 문자열이다. 출력해도 아무것도 안 나온다.
문자열에 원화표시 또는 백슬래쉬를 그대로 출력하고 싶을 때는 두 번 쓰면 된다.
처음에 문자열 선언 시 문자열 안에 ' 또는 "을 쓰고 싶으면 반대되는 따옴표로 문자열을 감싼다고 하면 된다고 했는데, 이렇게 이스케이프 문자를 이용해서도 사용 가능하다.
연한 색으로 나타낸 것들은 포스팅 안 하려다가, 갑자기 궁금해져서 막 찾아봤다.
\r(줄바꿈+커서 앞으로 이동)의 경우, 출력할 때 같은 줄에 계속 덮어쓰기를 하고 싶을 때 사용한다고 한다. 파일 복붙 할 때 이름이 같을 때 덮어쓰기 기능과 유사한 듯하다.
a = '안녕하세요'
b = '반갑습니다'
print(a, b)
>> 안녕하세요 반갑습니다
print(a, '\r', b)
>> 반갑습니다
첫 print문에서는 '안녕하세요'와 '반갑습니다'가 같이 출력됐는데, 중간에 \r을 넣었더니 '안녕하세요'는 덮어써져서 없어지고 '반갑습니다'만 출력된다. print에서는 기본 sep가 띄어쓰기로 되어있어서 두 번째 print문 출력 시 띄어쓰기하고 반갑습니다가 출력된다.
같은 내용을 \f(줄바꿈+커서 다음으로 이동)을 이용해서 다시 한번 출력해보겠다.
print(a, b)
>> 안녕하세요 반갑습니다
print(a, '\f', b)
>> 안녕하세요 반갑습니다
커서가 맨 앞으로 가지 않고 다음칸으로 이동했기 때문에 안녕하세요 반갑습니다가 한 줄에 출력되었다. 세 변수가 한 print문에서 출력됐으니 안녕하세요와 반갑습니다 사이에는 sep가 두 번 들어가서 두 번째 출력이 첫 출력보다 띄어쓰기가 더 되어있는 것을 확인할 수 있다.
\a와 \v는 생략... 주피터 노트북에서 돌려보니까 이런 게 나와서..
이게 왜 벨소리이고 수직 탭을 나타내는 것이란 말이냐..ㅠㅠ 더 공부를 하다가 알게 되면 그때 이 글을 수정하도록 하겠다.
3. 문자열에 번호가 있다! 인덱스(index)
문자열은 문자가 나열된 것이다. 고로 앞에서부터 번호를 정할 수 있다. 그 번호를 인덱스라고 부르고, 인덱스를 이용해서 원하는 문자만 쏙쏙 뽑아낼 수 있다.
i_say = "무지는 사랑이야"
i_say[1] # 첫번째니까 '무'가 나오겠지?
>> '지'
인덱스는 0번째부터 시작하기 때문에, 제일 앞 글자를 가지고 오려면 0번을 불러야 한다.
그럼 마지막 글자를 가지고 오려면?? (문자열 길이-1)번째를 불러오면 된다.
print(len(i_say))
>> 8
print(i_say[7])
>> 야
len 함수는 변수의 길이를 출력해주는 함수이다. i_say의 길이가 8이므로 마지막 글자는 7번째가 된다.
인덱스에 대해 조금 더 설명할 것이 있다.
파이썬은 음수 인덱스를 지원한다. 왜냐고 투덜거리는 사람도 있을 것이다. (저요 저요..) 문자열의 길이를 모르는 상황에서 마지막 값이 필요할 때가 많았어서 생긴 게 아닐까 생각해봤다.
i_say의 길이는 8였다. 마지막 글자는 7번째이면서 -1번째다. 나머지도 살펴볼까?
문자열 | 무 | 지 | 는 | 사 | 랑 | 이 | 야 | |
본 인덱스 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
음수인덱스 | -8 | -7 | -6 | -5 | -4 | -3 | -2 | -1 |
이렇게 보면 (본 인덱스) + (음수인덱스의 절댓값) = (문자열의 길이)라는 것을 알 수 있다.
인덱스를 이용한 코딩을 할 때, [0, 문자열의 길이) 또는 [-(문자열의 길이), -1] 범위의 인덱스만 유효하기 때문에, 이 범위를 벗어나면 에러가 발생한다. 수학에서 구간을 표시할 때 [ - 이상, ] - 이하, ( - 초과, ) - 미만으로 표시한다.
print(len(i_say))
>> 8
i_say[8]
>> IndexError: string index out of range
문자열의 길이를 꼭 확인해보고 코딩할 것을 권장한다!
4. 문자열 연산
문자열 연산은 많고많고많고많지만, (내가) 많이 쓰는 연산들만 소개하고, 차차 내공이 쌓여서 다른 것도 접하게 되면 조금씩 추가해 나갈 예정이다.
첫 번째, 문자열 잘라내기(slicing)이다.
a = '일이삼사오육칠팔구십'
print(len(a)) # a의 길이
>> 10
print(a[1:4]) # 1번 ~ 3번 출력
>> 이삼사
print(a[:6]) # 0번 ~ 5번 출력
>> 일이삼사오육
print(a[4:]) # 4번 ~ 끝까지 출력
>> 오육칠팔구십
print(a[:]) # 처음부터 끝까지 출력
>> 일이삼사오육칠팔구십
print(a) # 변하지 않아요!
>> 일이삼사오육칠팔구십
[시작:끝]을 써놓으면 [시작, 끝)에 해당하는 문자열을 잘라내준다. 물론 a는 변하지 않는다.
시작 또는 끝을 명시하지 않으면 처음부터 또는 끝까지로 인식한다.
두 번째, upper와 lower이다. 모든 문자열을 대문자 / 소문자로 바꿔준다.
b = 'pengsoo'
print(b.upper()) # 대문자로 바꿔주는 함수
>> PENGSOO
print(b) # 원래 변수는 변화 없음
>> pengsoo
b = b.upper() # 대문자로 바꾼 것을 변수에 할당
print(b)
>> PENGSOO
print(b.lower()) # 소문자로 바꿔주는 함수
>> pengsoo
print(b) # 역시 원래 변수는 변화 없음
>> PENGSOO
세 번째, replace이다. replace(a, b)를 쓰면 모든 a를 b로 바꿔준다.
c = '빅머니 가즈아 빅머니!!'
print(c.replace('빅', '스몰')) # 모든 빅을 스몰로 치환
>> 스몰머니 가즈아 스몰머니!! # 너무 슬픈 말이군
print(c) # 문자열에 영향 안줌
>> 빅머니 가즈아 빅머니!! # 다시 기뻐졌다.
네 번째, format이다. 값이 바뀌는 변수를 문자열에 넣고 싶을 때 쓴다.
lunch = '피자'
time = '오후 12시 30분'
# 약속을 정해서 톡 공지에 올렸다.
promise = '내일 {} 먹으러 가자! 시계탑에서 {}에 만나!'.format(lunch, time)
print(promise)
>> 내일 피자 먹으러 가자! 시계탑에서 오후 12시 30분에 만나!
# 다욧하는 무지맘이 애원했다.
lunch = '연어덮밥'
# 다들 다욧중이니 점심메뉴를 바꾸기로 했다.
promise = '내일 {} 먹으러 가자! 시계탑에서 {}에 만나!'.format(lunch, time)
print(promise)
>> 내일 연어덮밥 먹으러 가자! 시계탑에서 오후 12시 30분에 만나!
문자열 안에 {}을 이용해서 변숫값을 넣고 싶은 위치를 정한 다음. 문자열 뒤에 .format을 붙이고 앞에서부터 넣고 싶은 변수를 순서대로 입력하면 완성이다.
만약 두 번째 promise 선언을 하지 않았다면 점심메뉴는 그대로 피자다.. 다욧은 힘들어ㅠㅠ
마지막으로 볼 연산은 split이다. 특정 문자(정해주지 않으면 띄어쓰기)를 기준으로 문자열을 나눠서 리스트로 반환한다. (리스트는 데이터 타입, 연산자(3)에 설명되어있다.)
he_said = '나는.. 수줍음을 많이 타.. 어떻게 말을 하지..?'
she_said = '어떻게 하긴! 이렇게! 자신있게! 말하라고!'
print(he_said.split('..'))
>> ['나는', ' 수줍음을 많이 타', ' 어떻게 말을 하지', '?']
print(she_said.split('!'))
>> ['어떻게 하긴', ' 이렇게', ' 자신있게', ' 말하라고', '']
he_said는 ..을 기준으로 문자열이 나눠졌고, she_said는 !를 기준으로 문자열이 나눠진 것을 확인할 수 있다.
print(he_said)
>> 나는.. 수줍음을 많이 타.. 어떻게 말을 하지..?
print(she_said)
>> 어떻게 하긴! 이렇게! 자신있게! 말하라고!
물론 이것도 원래 변수에 영향을 주지 않는다.
<요약>
1. 문자열: 문자를 '작은따옴표', "큰따옴표"로 감싸기
2. 이스케이프 문자: 특별한 의미. \n, \t 등
3. 인덱스: 0번부터 시작하는 문자들의 위치
4. 문자열 연산
- slicing: 부분 추출
- upper, lower: 대/소문자 변환
- replace: 원하는 문자열로 교체
- format: 동적 문자열 생성
- split: 기준 문자로 문자열 나누기
'Python' 카테고리의 다른 글
데이터 타입, 연산자 (4) 딕셔너리, 셋 (0) | 2021.05.14 |
---|---|
작은 공간이지만 무한히 늘어날 지식 - 파이썬편 (0) | 2021.05.12 |
데이터 타입, 연산자 (3) 리스트, 튜플 (0) | 2021.05.11 |
데이터 타입, 연산자 (1) 숫자형, 논리형 (0) | 2021.04.22 |
변수 선언, 값 할당 (0) | 2021.04.21 |