강의로 돌아가기
이예진

코드 질문입니다.

def solution(L, x):
    idx = 0
    answer = []
    flag = True
    if x not in L:
        answer = [-1]
    else:
        while flag:
            try:
                if x in L[idx:]:
                    if answer:
                        idx = (L[idx:].index(x)+answer[-1])+2
                    else:
                        idx = (L[idx:].index(x))+1
                    answer.append(idx-1) 
                else:
                    flag=False
            except:
                flag = False
    return answer

저는 코드를 이렇게 작성했는데.. 어떻게 더 깔끔하게 짤 수 있는지 궁금합니다.

2 개의 답변
이시윤

우선 ifelse 로 이루어진 구조 내에서, else 절 내에는 들여쓰기 수준으로 다섯 번이 더 들어간 코드입니다. 만약 논리적으로 올바르다고 하더라도 이 정도까지 구조가 중첩하면 (while 내에서 try 내에서 if 내에 또다시 ifelse 가 있는?) 코드를 읽을 때 - 다른 사람이 읽으면 물론이거니와 코드를 쓴 자기 자신이 다시 읽을 일이 생길 때에도 - 그 내용을 명확히 파악하고 논리적인 구조를 이해하기가 어려워집니다.

이런 측면에서는 상당히 개선할 수 있는 여지가 있어 보입니다.

(1) 만약 `x` 가 `L` 안에 존재한다면 의 조건을 if x not in L 의 조건을 이용해서 판단했는데, 그 뒤에 또다시 idx 를 이용해서 if x in L[idx:] 로 되어 있네요. 같은 (또는 비슷한) 종류의 판단은 하나의 if 문을 이용하도록 바꿀 수 있지 않을까요? (그러자면 어떻게 순환문을 구성하면 될까를 생각해볼 수 있습니다. 한 가지 힌트는, 마지막으로 x 를 발견한 인덱스 또는 그 다음 인덱스를 변수에 기억하면서 순환문을 반복하면 어떨까요?)

(2) tryexcept 로 처리하려 하는 예외 (exception) 가 무엇인지 명확하지 않습니다. 이 프로그램에서 예외를 발생시킬 수 있는 것은 idx 가 리스트의 인덱스 범위를 넘어가거나, index() 메서드의 호출에서 리스트에 존재하지 않는 원소가 인자로 주어질 때인데, 전자는 순환문을 적절히 구성함으로써 (flag 보다는, 위에 언급한 마지막으로 `x` 를 발견한 인덱스 같은 것을 이용해서) 피할 수 있을 것이고, 후자는 이 코드에도 나와 있듯 if x in L[idx:] 와 같은 식으로 조건문을 붙여 피할 수 있을 것입니다.

(3) answerappend() 하는 인덱스를 계산한 식이 복잡합니다. 여기에서는 이미 answer 리스트 내에 먼저 들어간 인덱스가 있는 경우와 아닌 경우를 나누어 처리했는데, 위 (1) 과 (2) 를 참고로 하여 순환문의 제어를 보다 명확하게 하는 경우에는 (마지막으로 x 가 발견된 위치의 인덱스를 알고 있으므로) 두 가지 경우를 나누지 않고 훨씬 간단한 수식으로 계산할 수가 있게 될 것입니다.

(4) 위에서 말한 방식으로 순환문을 구성하여 리스트 내에서 x 가 발견되는 위치를 모두 answer 리스트에 기록한 뒤에, 만약 이 리스트가 비어 있다면 (한 번도 x 가 발견된 적이 없다면) answer = [-1] 로 처리하면, 가장 바깥쪽에 있는 if ... else 를 줄일 수 있으므로 이러한 상황에 대한 처리를 위한 코드의 구조가 보다 단순해질 것입니다.

이예진

답변을 참고하여 다시 짜보았습니다.
이 코드가 정답이 아닐 수도있지만..
로직이 개선되고 훨씬 깔끔해졌어요.
저에겐 생각의 전환이 필요한 것 같습니다.ㅎㅎ
감사합니다!

  • 방해되지 않게 코드는 지웠습니다.
  • 이예진
    추가로 L[idx:]에서 idx가 리스트의 인덱스를 넘어가면 index에러가 나는줄 알았는데 지금 보니까 빈 리스트를 반환하네요.. 이예진 2018.10.01 15:06
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다. 마크다운 가이드 를 참고하세요.