문자열에서 몇 가지 연산을 자주 하게 됩니다.
- 어떤 문자열 s가 문자열 s’를 가지고 있는가?
- 어떤 문자열 s가 문자열 s’로 시작하는가?
이 중, python startswith 함수는 2번째 경우에 쓸 수 있습니다. 굳이 특정 문자열로 시작하는데, in 연산자나 contains 를 쓸 이유가 없는데요. 이는 밑에서 후술하겠습니다.
python startswith 설명과 예제
먼저, 함수에 대한 설명 먼저 보도록 하겠습니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta1.png)
인자는 3개입니다.
- prefix
- prefix 패턴을 의미합니다.
- start
- 검사할 시작 위치를 의미합니다. 주어지지 않는다면 target의 맨 끝입니다.
- end
- 검사할 끝 위치를 의미합니다. 주어지지 않는다면 target의 맨 끝입니다.
이 중, prefix와 start 인자를 쓴 예제만 보여드리도록 하겠습니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta2.png)
먼저, 예제 1번을 보겠습니다. 1번째 줄과 2번째 줄 모두 타겟 문자열이 “abc” 임을 알 수 있습니다. 1번째 줄에 있는 startswith는, prefix로 “a”를, 2번째 줄에 있는 것은 prefix로 “b”를 받았습니다.
- 타겟 문자열 “abc”가 “a”로 시작하나요?
- 타겟 문자열 “abc”가 “b”로 시작하나요?
1번째 질문에 대한 답은 맞습니다. 2번째에 대한 답은 거짓입니다. 따라서, 1번 프로그램은, True와 False를 출력하게 됩니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta3.png)
결과를 보면 True, False가 공백으로 구분되어 출력되었음을 알 수 있습니다. 이제 “#{상품종류}{번호}” 형식으로 오는 데이터를 생각해 보겠습니다. 상품 종류가 음식이면 FOOD, 장난감이면 TOY라고 되어 있습니다.
상품에 대한 정보가 주어졌을 때, 상품 종류가 음식인지 어떻게 판단하면 좋을까요?
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta4.png)
contains로 검사해도 될 것 같지만, 일정한 형식이 있다면 역시 startswith를 쓰면 됩니다. # 뒤에 상품 종류가 나옵니다. 음식이면 # 뒤에 FOOD가 나올 것이고, 장난감이면 # 뒤에 TOY가 나올 겁니다. 따라서, 2번째 인자 start에 1을 넣습니다. 그러면 어떻게 검사할까요?
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta6.png)
타겟 문자열 전체가 아니라, 시작 위치 1부터 검사를 하게 됩니다. 즉, 노란 부분에 대해서 해당 부분이 “FOOD” 접두어를 가지는지 검사합니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta7.png)
FOOD 라는 접두어를 가지나요? 따라서 #FOOD2는 1번째 위치에서, FOOD 접두어를 가지게 됩니다. #TOY3은 그렇지 않고요. 따라서, 예제 2번 프로그램의 실행 결과는 아래와 같습니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta5.png)
여기까지 이해 되셨나요? startswith는 접두어가 prefix인지 검사하기 위해 쓴다는 점만 기억하세요.
왜 contains 대신에?
이런 의문이 들 수 있습니다. contains나 in이 있는데, 왜 접두어 검사에 startswith를 쓸까요? 이는 contains의 경우, 부분 문자열을 가지는지 검사하기 때문입니다. 이렇게 되면 종료 조건부터 차이가 나게 됩니다.
- 0번째 위치 ~ 1번째 위치를 탐색.
- 0번째 위치가 “F”가 아니면 끝.
- 1번째 위치가 “O”이면 “FO”가 접두어인 것이고, 아니면 거짓.
- 문자열의 시작 위치부터 끝까지 탐색하는 도중에 “FO”라는 패턴이 나오면 끝.
전자는 startswith, 후자는 contains의 종료 조건입니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta8.png)
“DOOFO2″에서, “FO”로 시작하는지 검사하려고 합니다. startswith를 썼다면, 0번째 위치가 “F”가 아닌 “D”이기 때문에, “FO” 패턴이 아닙니다. 따라서 여기서 종료됩니다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta9.png)
하지만, contains라던지 in의 경우, 맨 앞이 “D”로 시작되었음에도 불구하고 계속 탐색합니다. 이는, 함수 contains나 in이 부분 문자열을 가지는지 판단하기 때문입니다. 맨 뒤에 “FO”라는 패턴이 있을지도 모르고요. 불필요한 연산을 추가로 수행하기 때문에, 비효율적으로 동작하게 됩니다. 노란색 부분은 쓸데없이 탐색한 부분입니다.
index의 리턴값이 0인지 판단한다? 이 방법도 아닙니다. 왜냐하면, 저 문자열에서 “AO”를 찾는다고 해 봅시다.
![](https://codingdog.pe.kr/wp-content/uploads/2023/08/sta10.png)
끝까지 탐색하고도 못 찾았으니, -1이 리턴될 겁니다. 맞는 답이 출력되지만, 이미 문자열의 전체를 탐색하고 난 후입니다. 따라서, 단순히 prefix로 시작하는지 검사할 때에는, python startswith를 써야 합니다.