Python/파이선과 친해지기

[Python] - Python과 친해지기-문자열 기본과 in

문자열이란 무엇인가? 

훗. 이제 우리에게는 쉬운 소리다. 다들 알고 있다시피 문자열은 변하지 않는 리터럴이면서 큰따옴표(")나 작은따옴표(')로 둘러싸인 값을 의미한다. 이번 시간에는 파일 입출력을 제대로 공부하기 전에 문자열에 대한 여러 가지 이야기를 하고자 한다.

* 굳이 이걸 파일 입출력 전에 하는 이유는 파일 입출력과 파싱은 해당 언어에서 문자열에 대한 이해를 강요하기 때문이다. 필자 탓하지 말아 주라. 나도 파싱 할 때면 한숨부터 나온다.

 


문자열 함수

문자열에 대해서 처리되는 함수는 특정한 목적의 프로그램을 만드는 것이 아닌 이상 자주 사용되는 것이 정해져 있다.

 

아래 코드는 필자가 생각하는 적어도 이 정도는 알아야 문자열을 핸들링하는데 문제가 없을 것이라고 생각하는 수준의 함수들이다. * 가독성을 위해서 print문은 제외하고 함수의 반환문을 실행결과로 적어두었다.

>> my_label="PUT YOUR ILLINAIRE SIGN"
>> my_label.count("L")
2
## count함수는 문자열에서 셀 문자를 파라미터로 받고 그 수를 리턴한다. 추가적으로 int정수를 주어 
## count를 시작, 끝낼 인덱스를 지정할 수 있다.

>> my_label.encode("UTF-8")
b"PUT YOUR ILLINAIRE SIGN"
## 문자열을 UTF-8로 인코딩한다. 인코딩이란 컴퓨터 문자열의 집합인데, 우리가 보고 있는 글자,
## 심지어 이 글도 어떠한 문자열 집합으로 인코딩되어 있는 것이다.
## 리턴은 UTF-8로 인코딩된 문자열값(바이트) 이다.
## 문자열 앞에 b가 붙은건 이것이 바이트값임을 의미하고, 문자열이 아니다.

>> my_label.endswith("SIGN")
True
## 문자열이 파라미터로 넘긴 값으로 끝나는지 확인하여 bool값(True / False)를 리턴한다.
## 파일 확장자(.txt .png 등)를 검사할 때 유용한 기능이다.

>> my_label.find("YOUR")
4
## 파라미터로 넘긴 문자열이 몇번째 인덱스에서 시작하는지를 반환한다. 못찾으면 -1반환

>> my_label.join("aaa")
'aPUT YOUR ILLINAIRE SIGNaPUT YOUR ILLINAIRE SIGNa'
## 파라미터로 넘긴 값을 호출한 문자열(이경우에는 my_label)로 이어붙인다.
## 이 join함수는 문자열뿐만아니라 배열도 파라미터로 받을 수 있는데, 그 배열을 이어붙여 문자열로 
## 캐스팅하는 형태를 많이 쓴다.(ex : a=["1","2","3"]  >> "".join(a)의 출력은 "123"이 된다.)

>> my_label2 = "    s "
>> my_label2.strip()
"s"
## 문자열 앞뒤로의 공백을 제거한다. 공백또한 len함수에 포함이 되거나, 인덱스관련 작업을 방해
## 하는 경우가 많아 파일의 입출력 / 사용자의 입출력을 필터링하는데 주로 사용된다.

>> my_label.replace("YOUR","MY")
'PUT MY ILLINAIRE SIGN'
## 철수 교실에서 봤던 replace함수이다. 파라미터1의 문자를 파라미터2의 문자로 변환하여 리턴한다.

>> my_label.split(" ")
['PUT', 'YOUR', 'ILLINAIRE', 'SIGN']
## 문자열을 파라미터로 넘겨진 문자기준으로 나누어 배열을 생성하고 그 배열을 리턴한다.
## 위에는 " "으로 공백을 명시적으로 적어두었지만 생략하면 자동으로 공백을 기준으로 실행된다.

이 외에도 문자열의 처음을 대문자로 해주는. capitalize()나 모든 문자를 대소문자로 만드는 upper()와 lower(), 이들을 검사하는. is뭐 함수, tab을 space로 변환해주는. expandtabs() 등 여러가지 함수들도 많다. 한 번씩 찾아보는 것도 실력 향상을 위해서 알아두면 좋다.

 

특수문자의 사용

애초에 큰따옴표(")나 작은따옴표(')가 문자열의 시작과 끝으로 인식이 되고, 저번 시간에 본 \n NewLine처럼 예약된 특수문자가 있다 보니 문자열을 사용할 때 특수문자를 처리하고 싶으면 다음 표를 참고해서 처리해야 된다.

특수문자 해석
\ 다음 줄의 연속
\' 작은 따옴표(')
\" 큰 따옴표(")
\\ \문자
\n New Line
\t TAB

* 이 특수문자들은 문자열 안에서 쓰일 때 해석으로 변환되어 사용된다.

* 문자열 앞에 r을 붙이면"(ex : r"PUT YOUR \t ILLINAIRE \n SIGN") raw문자열로 해석되어 이러한 특수문자가 해석으로 치환되지 않고 그대로 출력된다. 한 번씩 해보길 바란다. 이게 파일 경로를 처리할 때 도움이 많이 된다. (ex : C\USERS\USER은 \가 들어가 특수문자 처리를 위해 \\로 입력을 해야 되는데 raw로 변환하면 그냥 경로 그대로 처리 가능하다.)

 

예약어 in, is, not

딱히 어디에 넣기 애매해서 문자열 기본 포스팅에 in의 사용법을 올리게 되었다. 나중에 적당한 포스팅이 생기면 is의 설명은 이곳의 설명 범위를 벗어나기에 이동할 예정이다. in과 is 그리고 not은 Python에 이미 정의된 예약어인데, 논리 연산자와 비슷한 역할을 한다.

>> a = [1,2,3]
>> 1 in a
True

>> 3 not in a
False

>> my_val = "ILLINAIRE"
>> "ILL" in my_val
True

>> b = [1,2,3]
>> a is b
False

in의 사용법은 위와 같이 in뒤의 값이 in앞의 값을 포함하고 있는지를 판단하여 True, False로 반환한다는 점이다. is, in, not모두 조건문의 조건으로 많이 사용한다.

 

*a is b가 False인 이유(이 시간의 내용을 벗어난다, 더보기 참조)*

더보기

이는 is라는 예약어가 비교하는 두 대상이 같은 메모리를 가리키는지를 판단해서 그렇다.

 

변수를 생성을 하면 변수의 이름은 특정한 메모리 공간과 매칭이 되는데, (예를 들면 위 상황에서 a라는 변수는 호텔방 101호를 배정받은 거고 b라는 변수는 102호를 배정받은 거다)  같은 곳을 가리키고 있는지 검사하는 is의 특성상 값이 같더라도 객체가 달라 다르다고 판단을 한다.(101호에 치킨이 있고 102에 치킨이 있어도 이는 다른 방이기에 is는 False를 반환한다.)

 

따라서 값을 비교하는 경우라면 ==을 사용하는 것이 현명하다. (단 리터럴 문자와 변수를 비교할 경우 값이 같을 경우 True를 반환한다. 이는 리터럴에 대한 메모리 재활용 덕분인데, 이는 이 포스팅의 설명 범위를 한참 벗어난다.)

 


이번 시간에는 파일 입출력에 들어가기 전 문자열을 조금 더 자유자재로 다룰 수 있는 기초 다지기 시간을 가져보았다. 함수를 모두 외울 필요는 없다. 그걸 다 머리에 넣고 있다고 좋은 프로그래머라고 단정할 수 있는 사람은 없다.(오히려 프로그래머라면 메모리 낭비라고 화낼 것이다.) 필요한 기능이 생기면 Python 공식 API 등을 찾아봐서 찾아 쓰는 것을 추천한다. 실력을 늘릴 수 있는 좋은 방법이다.