서울에서 김서방 찾다가 for문 이해!

히제오·2020년 10월 3일
2

파이썬 til

목록 보기
2/9
post-thumbnail

서울에서 김서방 찾기는 역시 어려웠다.
프로그래머스가 내게 서울에서 김서방을 찾아보라며 준 문제는 다음과 같았다.

String형 배열 seoul의 element중 Kim의 위치 x를 찾아, 김서방은 x에 있다는 String을 반환하는 함수, solution을 완성하세요. seoul에 Kim은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.

  • 제한 사항
    - seoul은 길이 1 이상, 1000 이하인 배열입니다.
    - seoul의 원소는 길이 1 이상, 20 이하인 문자열입니다.
    - Kim은 반드시 seoul 안에 포함되어 있습니다.

  • 입출력 예
seoul	        return
[Jane, Kim]	김서방은 1에 있다

물론 나는 파이썬을 막 배우기 시작했고! 삽질이 당연하다!
그러다가 실행했을 때 테스트 케이스는 통과했는데 정답은 아니라는 이상한 결과를 맞닥뜨리게 됐다.
파이썬 함수의 for문을 이해 못해서 발생한 삽질이었다.

사건은 이랬다...

김서방 찾기를 수업 중 배운 내용이 아니라, 여기저기 돌아다니다 찾은 index 함수로 풀어낸 것이 영 못마땅해서 조교님께 힌트를 구했더니 조교님께서 for문과 range(len(seoul)), 그리고 예상하시는 작동 단계를 힌트로 주셨다. (지금 보니 다 주셨네요...)

아하! 하고 바로 문제풀이에 돌입. 아래와 같은 코드를 짜고, 테스트 케이스를 실행해보고 통과했다! 그러나 제출하면 답은 아니라고 하는 기이한 현상을 마주해야만 했다...

def solution(seoul):
    for x in range(len(seoul)):
        seoul[x] == "Kim"
    return "김서방은 {}에 있다".format(x)

테스트 케이스에 희생된 현진님... 마침 화상스터디판옵티콘에 계셔주셔서 동의 없이 희생되었나이다 이것을 찾아서 저를 방문해주신다면 선물을 드립니다

내가 짠 코드의 의도를 한국말로 풀이해보면, 'x가 range 범위 안에 있는 여러개의 수 중에서 하나인데, x는 seoul의 인덱스이고 seoul[x]는 "Kim"을 출력해. 그 값을 가지고 "김서방은 x에 있다"를 리턴해봐'

아시는 분은 바로 보이시겠지만 range를 완전히 잘못 이해했지요...무엇을 잘못 이해하고 있었냐면

  1. for문을 변수 설정을 위한 장치로만! 이해해버림.
  2. in range를 '이 범위 안에 있어요' 정도로 이해해버림.

어쨌든 통과가 안 나와서 이해는 못 한채로 여러 삽질을 하다가 이런 코드를 짰고, 통과를 했다.

def solution(seoul):
    for x in range(len(seoul)):
        seoul[x] == "Kim"
        if seoul[x] == "Kim":
            return "김서방은 {}에 있다".format(x)

하지만 여전히 이해가 안 됐다. seoul[x] == "Kim" 의 코드를 통해 변수를 만들어냈다고 생각했는데, 왜 if 절이 필요한거지? 라고 생각한 거다.

그렇게 또 조교님을 괴롭혔고... for문과 range에 대한 놀라운 사실이게 놀라웠다니 또르륵을 알게 된다

보내주신 코드에서 첫번째 코드인, if 문이 없는 코드에 대해서 살펴보면, return은 for문이 전부 돌고나서, x의 "마지막값"이 return문에 포함되게 됩니다. 그래서 예제는 문제없지만, 만약 seoul 이라는 리스트의 값이 ["Han", "Kim", "Park"] 일 경우에 정답인 "김서방은 1에 있다" 가 아니라, "김서방은 2에 있다"라는 값이 나오게 됩니다. for문을 range(len(seoul)) 만큼, x가 2가 될때까지 반복문을 수행하다가 가장 마지막으로 return문이 동작하기 때문입니다.

충격... 충격... 내 코드가 이 테스트케이스의 허점을 이상한 방식으로 찔렀던 것이다...! 내 코드는 그냥 seoul의 length만큼 for문을 돌고나서 마지막 x 값을 return에 포함했을 뿐인 것이고... 그래서 "김서방은 seoul의 length에 있다"는 이상한 결과가 return됐을 뿐이고... 마침 "Kim"은 테스트케이스의 리스트 마지막에 있었고... 내가 잘 이해해보겠다고 만들었던 테스트 케이스도 하필 "Kim"을 맨 마지막에 넣었고... 그래서 정답 처리는 안 됐던 것이다.

알고보니 통과한 코드에서도 seoul[x] == "Kim"부분은 필요하지 않았다. 아래와 같은 코드가 사실 '정답코드'라고 할만한 것이었다.

def solution(seoul):
    for x in range(len(seoul)):
        if seoul[x] == "Kim":
            return "김서방은 {}에 있다".format(x)

이 함수의 for문 작동방식을 한국말로 해석해보면, 'for문 아래의 작업을 len(seoul)만큼 반복해주고, return값이 나오면 거기서 스탑할거야.' 정도로 이야기할 수 있겠다. 좀 더 구체적으로 말하자면 for문 내에 if 문이 포함되어 있어서, if의 조건문이 True일 때 return을 하고, 그 경우 for문의 반복은 중지되고 함수가 끝나는 것!

김서방 찾다가 for문이 "반복문"이라는 것을 찐하게 깨닫고 간다. 다시 한 번 조교님 감사드려요... 🥺

profile
삽질 전문가. 모든 일에 진심인 편.

0개의 댓글