[02주차] String

Sung-E-Gkoght·2022년 11월 16일
0

HYAI - Python class

목록 보기
10/17

3-1. 문자열(String)

Python은 문자열을 비교적 자유롭게 다룰 수 있습니다!

  • 문자열 식
  • 문자열 인덱싱과 슬라이싱

문자열이 기본적으로 무엇인지, 어떤 역할을 할 수 있는지 알아보고, 위의 두 내용을 설명해드리도록 하겠습니다.

3-1-1. 문자열(String)의 의미와 표현방법

아래 요약입니다. 서술이 장황하고 어려워서 요약만 보셔도 될 것 같아요...

문자열은 문자의 나열이다. Python은 문자의 개념을 짧은 문자열로 설명한다.



문자열은 그 이름대로 "문자의 나열"입니다. 사실 "문자의 나열이 뭐가 특별한가?"라고 궁금해하실 수 있습니다. 하다보면서 그렇게 느낄 수도 있는 부분이죠.

다른 언어에서는 문자와 문자열이 분명히 다릅니다. 단일 문자(Character)가 홑따옴표( ' )로 둘러쌓여 있으면 그게 문자(여기서 말하는 문자는 Character literals)이고, 문자가 쌍따옴표( " ) 안에 나열되어 있다면 그건 문자열(String, String literals)입니다.

그러나 Python에서는 그렇지 않습니다. ( ' )든 ( " )든 모두 문자나 문자열을 표현하는 데 사용할 수 있고, 실제로 Python의 관점에서는 string밖에 없습니다. 아래는 IBM에서 제공하는 C언어 문서와 Python측에서 제공하는 Python 공식 문서의 일부입니다.

https://www.ibm.com/docs/ko/i/7.4?topic=tokens-literals#conref
이곳의 항목에는 Character literals라는 항목이 있지만,

https://docs.python.org/3.10/reference/lexical_analysis.html#literals
이곳의 항목에는 Character literals라는 항목은 없습니다. 오히려 String literals 부분에 shortstring이라는 용어가 있는데요, 이건 BNF표기법을 알아야 하기 때문에 이 이상으로 알아보긴 어려울 것 같습니다.

다만 문자(Character literals)라는 강의에서 포기하긴 어려울 것 같습니다. 이따가 문자열도 일종의 sequence라는 사실을 배울텐데, 그때 shortstring이라는 말보다는 문자라고 말하는 게 더 쉽지 않을까 하는 생각이 들었습니다.

문자의 나열은 문자열이다. 그러므로 문자열은 문자 하나하나가 나열되어 있다.

이미 말 자체에서부터 이해하기 쉬우니까요.

그래서 아예 literals라는 말도 빼고 그냥 "문자"라는 말을 넣어서 설명할게요.



기억하셔야 할 것은 네 가지입니다!

  • 문자열은 문자들을 ' 로 감싸서 만들 수 있다.
  • 문자열은 문자들을 " 로 감싸서 만들 수 있다.
  • 문자열은 문자들을 """ 로 감싸서 만들 수 있다.
  • escape 문자가 무엇이고 어떤 역할을 하는가.

문자열에 대한 예시를 보도록 하겠습니다.

우선 아무런 따옴표도 넣지 않은 경우입니다. 이전에 배웠던 숫자형(Numeric data types)는 그냥 입력하거나 계산식을 넣어도 문제가 없지만, 문자나 문자열을 넣는 경우에는 그렇지 않습니다.

invald syntax라고 하면서 문법이 잘못 되었음을 말해주고 있습니다.


이번엔 일반적으로 문자열(string)을 표현할 때 사용하는 쌍따옴표( " )로 감싸서 입력해본 경우입니다.

오류가 나지 않습니다. 출력 결과에서 홑따옴표( ' )로 나오기는 하지만 문제라고 할 만한 것이 보이지 않습니다. 출력할 때 특별한 경우가 없다면 홑따옴표가 기본(default)로 설정되어 있는 모양입니다.


다음에는 일반적으로 문자(Character를 표현할 때 썼던 ( ' )로 감싸서 입력해본 경우입니다.

마찬가지로 아무런 문제가 발생하지 않습니다.


+필요할 지는 모르겠지만 문자열 안에 '나 "를 넣고 싶은 경우도 있을 겁니다.

I'm strong

이라는 문장을 문자열로 만들어볼까요?

' 와 " 모두 문자열을 표현하는 데 사용이 가능하기 때문에, 가장 바깥쪽을 "로 감싸주기만 한다면 문제가 없습니다.

일부로 하나를 더 넣어도 다른 점은 없습니다. 사용자가 따로 명령을 내리지 않았지만, 문자열을 만드는 기능을 잃고 일반적인 문자가 된 것을 볼 수 있습니다.

그런데 만약

I'm "very" strong

을 출력하고 싶다면 어떻게 해야 될까요?

이럴때 우리는 "\" 문자(탈출문자, escape character)를 사용합니다. windows 유저라면 원화 표시로 보이고 Mac 유저라면 Back-slash로 보입니다.

\"

이것의 의미는, 원래 ' 는 문자열을 만드는 문자였습니다. 그런데 앞에 escape 문자를 붙여서, 이름처럼 원래 기능에서 탈출(escape)했다는 뜻입니다. 그 결과로 일반적인 문자가 되어 양 끝의 "와는 다른 문자가 된 것이죠. 참고로

\"  이 자체가 하나의 문자입니다.

원래 기능에서 탈출했다고 하면 기능을 잃어버리는 것으로 생각할 수도 있지만, 그 반대가 오히려 더 많습니다. 대표적인 두 가지만 보여주고 다음 내용으로 넘어가도록 하겠습니다.

  • \n : 개행문자 - newline
  • \t : 탭 문자 - vertical tab (tab은 이전에 들여쓰기에서 본 적이 있습니다)

escape 문자의 활용은 여기서 끝이 아닙니다. 다음 예시를 봅시다.

"I'm
very
strong"

원래 한 줄이었던 문자열을 세 줄로 만드려고 했습니다. 그런데 에러가 발생했다고 말해주고 있습니다.

Python에서 문자열은 ' 또는 " 로 시작을 했다면 그 줄(line)에서 각각 ' 또는 " 로 다시 닫아주어야 합니다. 그래야만 인식이 됩니다. 해결방법은 두 가지로, escape 문자를 사용하는 방법과 """으로 여닫는 것입니다.

  1. escape문자 사용

  2. """으로 여닫기

두 방법의 차이점은 \n를 포함하냐 포함하지 않느냐로 볼 수 있습니다. 필요에 따라 선택하면 될 것 같습니다.
("그럼 도대체 1번은 왜 쓰는 건가?" 라는 의문이 생길 수 있습니다. 그 이유는 한 줄에 너무 많은 내용이 들어가는 경우입니다. 그렇게 되면 화면에 한 번에 표시할 수 없어져버리는 일이 종종 생깁니다. 이럴 경우에 가독성을 위해 escape문자(\)를 사용할 수 있습니다.)

(더하여 \는 문자열이 아니라 코드를 짤 때도 줄바꿈을 도와줄 수 있는데, 이 부분에 대해서는 Python 기본 문법 추가자료를 구성하고 있습니다,,, 다만 시간이 없어서 언제 올라갈 수 있을지는 모르겠습니다,,,)

3-1-2. 문자열(string)식(evaluation)

Python은 문자열(string)에 다음과 같은 연산이 가능합니다.

  • 덧셈
  • 곱셈
  1. 덧셈( + )
    예를 들어서 다음의 두 문자열이 있다고 해봅시다.

    "중요한 것은"
    "꺾이지 않는 마음"

두 문자열을 이용해

"중요한 것은 꺾이지 않는 마음"

을 만들어봅시다. 뭔가 두 문자열을 이어붙인 것 같지 않나요?

다음과 같이 이어붙일 때 "+" 연산자를 이용합니다. (+가 문자열이라는 뜻이 아닙니다.)

그런데 중간에 띄어쓰기가 없습니다. "+"가 알아서 띄어쓰기를 해줄 수는 없거든요. 두 문자열을 수정 가능하다면

"꺾이지 않는 마음"을 " 꺽이지 않는 마음"으로 바꾸어주면 되고(또는 "중요한 것은 "), 수정이 불가능하다면

이렇게 만들어줄 수도 있습니다. 그런데 "와 " 사이에 스페이스바 한 번을 입력했는데 그대로 남아있습니다! 왜냐하면 띄어쓰기를 포함한 공백문자(White-space character)도 문자입니다. 개행을 할 때 누르는 "Enter"키도 눈에 보이지는 않지만 실제로 프로그램 안에 존재한답니다. 문자는 원래 '나 "와 함께 입력하지 않으면 오류가 났지만, 공백문자는 괜찮습니다.

  1. 곱셈( * )
"중요한 것은 꺾이지 않는 마음"

이라는 문자열을 만들어내는 데 성공했습니다. 이 문자열을 세 번이나 출력하고 싶으시다면 어떻게 해야 할까요?

"*" 연산자를 사용하여 세 번을 반복할 수 있었습니다. 이걸 세 줄에 걸쳐서 출력한다고 하면

개행문자를 활용해서 시도할 수 있었습니다. 다만, print( )함수 없이 입력하면 개행문자가 적용되지 않는 걸 보실 수 있는데, REPL은 내용 자체를 보여주고 print( )는 표준출력을 해주기 때문입니다.


3-1-3. 문자열 인덱싱(indexing)과 슬라이싱(slicing)

문자열(string)을 변수(variable)에 저장하면 어떻게 될까요?

내용 자체를 보기 위해 print( )함수를 사용하지 않고 출력해보았습니다. 다행히 큰 변화가 없어 보입니다. 그런데 정말 갑자기 세 번째 글자를 출력하고 싶어졌습니다! 어떻게 해야 할까요?

  1. 우리는 sequence타입에서 원소 하나를 지정해서 그 값을 받는 것을 인덱싱(indexing)이라고 부릅니다. 문자열은 sequence타입에 속하고 문자열의 원소는 문자라고 할 수 있습니다! 문자열에 대괄호 [ index ]를 해주는 것으로 인덱싱할 수 있습니다. 여기서 인덱스(index)는 어떤 문자열에 속한 문자의 위치입니다.

그런데 뭔가 이상합니다. 세 번째 위치의 문자는 분명 '한'일 것이라고 생각했는데, 공백문자가 나온 것일까요.

그 이유는 사실 인덱스(index)의 시작이 0부터 시작하기 때문입니다! 1번째, 2번째, 3번째, ... 으로 가지 않고 0번째, 1번째, 2번째, 3번째, ... 인 셈이죠.

a[3]

그래서 사실 위의 코드는 a에 저장된 sequence의 "4번째" 원소를 지정했던 것이죠. 추가로 사진에서 볼 수 있듯이 Python은 음수 index도 지원합니다.

"중요한 것은 꺾이지 않는 마음"

그런데 이번엔 "꺾이지 않는 마음"을 값으로 받고 싶어졌습니다. 이건 어떻게 해야 할까요?

  1. 우리는 sequence타입에서 특정 인덱스 범위에 있는 원소들을 복사해서 가져오는 것을 슬라이싱(slicing)이라고 합니다. 인덱싱과 마찬가지인데, 차이점은 범위가 다르다는 것이죠.

'꺾'은 7번째 index, '음'은 15번째 index이니 7번부터 15번까지라는 의미에서

a[7:15]

를 입력했는데, 15번 index의 원소 '음'은 함께 출력되지 않았습니다.

[x:y]

그 이유는 위와 같이 슬라이싱할 때 x번째부터 y번째 "전까지"이기 때문입니다. 그러니 '음'은 포함되지 않았던 것이죠. 이럴때는 어떻게 해야 할까요?

y을 지정하지 않는다면 대상 sequence의 끝까지 복사하게 됩니다. 여기서 대상 sequence는 a( = "중요한 것은 꺾이지 않는 마음")이므로 '꺾'부터 시작해서 끝까지 복사한 것이죠. 물론 이 반대도 가능합니다.

주의하셔야 할 점은 slicing이라는 표현 때문에 원본에서 "잘라놓는다"라고 오해할 수 있는데, 원본은 유지된다는 점입니다.

참고로 b를 출력할 때 띄어쓰기가 있는 이유는 print( ) 함수가 출력할 대상을 ","로 구분하는데, 기본적으로 띄어쓰기 한 칸을 해주기 때문입니다:)

인덱싱과 슬라이싱은 문자열뿐만 아니라 다른 sequence 타입의 데이터에도 사용 가능합니다. 꼭 기억해주셨으면 좋겠습니다.


3-1-4. 타입 변화를 위한 내장함수(built-in function)

Numeric types와 String은 서로 타입 변화가 가능합니다.

i) String to Numeric types

먼저 다음과 같은 방법으로 integer와 float을 string으로 바꿀 수 있습니다.

변환하려는 대상이 정수(나 실수이기만 하다면 바꿀 수 있습니다.

ii) Numeric types to String

String을 integer나 float으로 바꾸는 데에는 제약이 있습니다.

  1. string to integer
    integer로 바꿀 때는 문자열이 정수(integer)로 이루어져 있어야 합니다.

정수가 아니라면 에러가 납니다.

  1. string to float
    float으로 바꿀 때는 문자열이 정수(integer) 또는 실수(float)로 이루어져 있어야 합니다. 정수인 경우는 묵시적으로 실수로 바꾸어 줍니다.

정수나 실수가 아니라면 에러가 납니다.

  1. 추가로 문자열이 수식의 모양을 띄는 경우 헷갈릴 수 있습니다.

    이 경우는 그저 연산자 모양의 문자가 있는 것일 뿐 실제 연산자가 아닙니다.

+) integer <-> float


사실 잘 쓰지는 않는 것 같습니다. 첫 번째의 float -> integer의 경우는 데이터가 손실되고, 두 번째의 integer -> float의 경우는 특별할 게 없으니까요.


3-1-5. 문자열 관련 함수

https://wikidocs.net/13#_20

위의 링크에서 11개의 문자열 관련 내장 함수(Built-in function)을 설명하고 있습니다. 이미 설명과 사용법이 모두 나와 있기 때문에, 시험을 보는 게 아니라면 외우기를 바라지는 않습니다. 언제든지 찾아볼 수 있기 때문이죠.

대신 꼭 한 번씩 따라서 입력해보시기를 바랍니다.


사진 출처:
https://www.programiz.com/python-programming/list

profile
Sung-E-Gkoght

0개의 댓글