# 문자열형(String)

Python의 기본에서도 문자열은 다루웠습니다. 하지만 자료형으로써 문자열 내용은 ㅊ조금 부족했습니다. 이번 내용은 문자열형 자료형에 대해서 좀 더 살펴보기로 합니다.

```python
head = 'Life is short!! '
tail = 'You need Python!'
combine = head + tail

print(head)
print(tail)
print(combine)
```

1행과 2행은 각각 head와 tail이라는 변수를 통해서 문자열형 자료를 대입했습니다. 그리고 새로이 combine이라는 변수를 통해서 두 개의 문자열을 하나로 합쳤습니다.

5행, 6행, 7행은 각각 별도의 변수들을 출력하여 그 내용을 살펴보게 됩니다. 위의 내용처럼 7행은 head와 tail이 합쳐진 변수가 출력되게 됩니다.

```python
equal = '='
title = 'Life is short. You need Python!!!'

print(equal * 33)
print(title)
num = 33
print(equal * num)
```

Python의 재밌는 특징 중 하나는 문자열 곱셈이라는 연산 방법입니다. 물론 실제로는 연산이라고 하기에는 그렇고 동일한 문자열을 주어진 숫자만큼 반복하는 것을 의미합니다. 4행과 6행은 각각 '='이라는 문자열 변수를 33회 반복해서 출력하는 내용입니다.

윗 문단에서 문자열의 곱셈은 실제 연산이 아니라고 언급했습니다. 이것은 문자열 \* 문자열, 문자열 + 숫자와 같은 것은 허락되지 않는 것을 의미합니다.

```python
head = 'Life is short!'
tail = 'You need Python'

print(head*tail) #Error
print(head+tail)
print(head+3) #Error
```

## 문자열 인덱싱(String indexing)

Python은 문자열을 너무나 쉽게 사용할 수 있게 해줍니다. 하지만 문자열은 실제로 각각의 문자의 합으로 구성되어 있으며, 특정 메모리 주소에 순서적으로 위치해 있습니다. 때문에 문자열형 변수는 해당 문자열의 특정 위치에 존재하는 문자열을 보고나 참고할 수 있습니다.

```
Life is Short! You Need Python!!
          1         2         3
01234567890123456789012345678901
```

1행의 문자열은 공백과 느낌표를 포함해서 총 32개의 문자로 구성되어 있습니다. 2열과 3열의 각 문자에 대한 순서를 기록한 것입니다. 제일 처음의 'L'의 경우는 인덱스 0입니다. 그리고 Python의 'P'는 인덱스 24입니다.

```python
var_string = 'Life is Short! You Need Python!!'

print(var_string[0])
print(var_string[24])

print(var_string[-1])

print(var_string[-32])
print(var_string[-8])
```

3행과 4행은 위의 설명과 같이 'L' 과 'P'를 출력하는 내용입니다. 여기서 주목해봐야할 것은 -의 사용입니다. -을 사용해서 표현하면 가장 끝의 자리부터 인덱싱을 시작합니다. 실제로 8행과 9행은 3행과 4행과 동일한 내용입니다. 그러나, 앞에서부터 인덱싱을 하는 것이 아니라 가장 끝에서부터 인덱싱을 한다는 차이가 있습니다.

주의 해야 할 점은 앞에서부터 인덱싱을 할 경우 그 순서가 0부터 시작하지만, 끝에서 부터 시작하는 것은 -1부터 시작한다는 점입니다.&#x20;

**참고** 문자열 인덱스는 1바이트를 기준으로 되어있습니다. 따라서 한글로 된 문자열의 경우 위와 같은 인덱싱을 사용하여 특정 문자를 가져올 수 없습니다. 한글과 같은 유니코드(Unicode)는 2바이트 형식이기 때문에 이 방법을 사용하면 깨진 문자만을 확인하게 됩니다.

## 문자열 슬라이싱(String slicing)

위 내용으로 문자열은 인덱스를 가지고 있다는 알았습니다. 그럼 이러한 인덱스로 무엇을 할 수 있는지 간단히 살펴보도록 하겠습니다.

```python
var_str = 'PYTHON'

print(var_str[0:3])
print(var_str[2:5])
print(var_str[2:])
print(var_str[:3])

print(var_str[-6:-3])
print(var_str[-4:-1])
print(var_str[-4:])
print(var_str[:-3])
```

위의 예제를 문자열을 잘라내서(슬라이싱) 출력하는 방법의 예입니다. 인덱싱부분에서 언급한 것과 같이 정방향 인덱스와 역방향 인덱스 둘 다 사용할 수 있습니다.

3행의 경우 var\_str의 0번째 인덱스부터 3번째 인덱스의 바로 앞 문자까지 출력하는 내용입니다. 즉 인덱스0부터 2까지의 'PYT'만 출력됩니다.&#x20;

5행의 내용은 2번째 인덱스부터 끝까지의 내용을 출력한다는 내용입니다. 반면 6행은 앞부터 인덱스 3전까의 내용만을 출력한다는 내용입니다. 다양한 형태로 슬라이싱을 할 수 있다는 점을 기억해둡시다.

8행부터 11행은 3행부터 6행까지의 내용과 동일합니다. 다른 점이 있다면 역방향 인덱스를 사용한다는 점입니다.&#x20;

## 문자열 메소드(String Method)

프로그래밍에서 메소드는 클래스(Class)서의 함수 역할을 하는 부분을 지칭합니다. 메소드에 관한 내용은 이후 함수나 클래스에서 더 다루기로 하고 우선 이러한 것이 있다는 것만 알고 넘어가도록 하겠습니다.

문자열은 많이 사용되는 자료형인 만큼 다양한 메소드들이 있습니다. 여기서는 그 중에서 몇 가지에 대해서 알아보도록 하겠습니다.

```python
var_str = 'Life is short! You need Pyton!!'

print(var_str.upper())
print(var_str.lower())
print(var_str.title())
print(var_str.swapcase())

print(var_str.count('e')
print(var_str.find('Python')

print(var_str.endswith('?')
print(var_str.endswith('!')
print(var_str.startswith('l')
print(var_str.startswith('L')
print(var_str.lower().startwith('l'))

var_list1 = var_str.split()
print(var_list1)
var_list2 = var_str.split('! ')
print(var_list2)
```

3행은 변수인 var\_str을 모두 대문자로 변경하는 내용입니다. 이와 반대로 4행은 모두 소문자로 변경합니다. 5행은 문자열에서 각 단어의 시작을 대문자로 변경하는 내용입니다. 그리고 6행은 소문자와 대문자를 변경하는 내용입니다.

8행은 문자열에서 'e'가 몇 번 존재하는지를 출력합니다. 9행은 문자열에서 'Python'이라는 단어를 찾아서 해당 문자열의 몇 번쨰 인덱스에서 시작하는지를 알려줍니다.

11행부터 15행은 var\_str인 특정 문자 또는 문자열로 시작하거나 끝나는지를 묻는 내용입니다. 이 경우에는 부울형으로 내용을 출력하게 됩니다. 15행에 보면 소문자 'l'로 시작함을 측정하기 위해서 먼저 var\_str 전체에 대해서 소문자화하여 내용을 확인하는 것을 볼 수 있습니다. lower(), upper(), title(), swapcase() 등의 메소드는 문자열형으로 자료형을 반환하고, 이에 대해서 바로 또 다른 문자열 메소드를 사용할 수 있습니다.

17행은 다소 선행적인 내용입니다만,  split() 메소드로 리스트를 만드는 것을 확인할 수 있습니다.(리스테에 관해서는 이후 자료구조 부분에서 좀 더 자세히 다루도록 하겠습니다.) split()에 아무런 인자가 입력되지 않았을 경우에는 공백(스페이스 'space')으 기준으로 문자열을 분리합니다. 반면 19행과 같이 특정 문자 또는 문자열을 인자로 주면, 인자에 맞게 내용을 나눠서 리스트를 생성하게 됩니다.
