강의로 돌아가기
이유찬

파이썬 초보라, 여기서 더 개선해볼 수 있을까요?

부랴부랴 강의 보려고 파이썬 공부를 엄청나게 빨리 하고 있습니다. 코드 순서는

  1. L[0] 과 x를 비교해서 x가 더 작으면 앞에 넣고
  2. for 문을 사용해서 다 확인한 후
  3. 마지막으로 L.append(x)로 넣었습니다. 코드 개선사항.. 군더더기? 필요 없는 부분이나 더 간략하게 줄일 수 있는 있을까요??
작성중인 코드―solution.py
1
2
3
4
5
6
7
8
9
10
11
12
13
def solution(L, x):

    if x <= L[0] :
        L.insert(0, x)
        return L

    for c in L:
        if x <= c :
            L.insert(L.index(c), x)
            return L

    L.append(x)
    return L
1 개의 답변
이시윤

우연히도, 줄일 수 있는 부분이 있네요.

제 3 행부터 제 5 행에 걸친 if 문장은 필요하지 않습니다. 만약, 이 if 조건이 참이 되는 경우 (즉, x 가 리스트의 첫번째 원소인 L[0] 보다 작거나 같은 경우) 라면, 뒤의 (제 7 행부터 시작하는) for 순환문의 첫번째 단계에서 처리될 것이기 때문입니다. 조금 다르게 풀어 말하면, 제 3 행부터 시작하는 순환문은 제 7 행부터 시작하는 순환문에 논리적으로 포함되는 관계를 가지고 있습니다.

그 뒤는 좋습니다. 그런데, (알고리즘 문제 풀이에서는 크게 신경쓰지 않는다고 해도) 소프트웨어 개발에서는 단지 알고리즘을 올바르게 수행하는 기능적 부분 외에도, 코드의 형태에 있어서도 (프로젝트별로 다를 수 있는) 코딩 규약 (coding convention 또는 coding style guideline) 을 따르도록 하는 경우가 대부분입니다. 많은 경우, L10 (제 10 행) 에서처럼 if 내에 리턴 문장이 포함되는 것을 금지 또는 비권장합니다. 그렇게 하는 것이 구조적으로 더 나은 경우도 있을 수 있지만, 이 경우에는 아래와 같이 쓰는 것이 더 나아 보입니다.

def solution(L, x):
    for i, c in enumerate(L):
        if x <= c :
            L.insert(i, x)
            break
    else:
        L.append(x)
    return L

또 하나 눈여겨 보시면 좋은 부분은, 위 코드에서는 index() 메서드를 이용하지 않고 리스트에 대한 enumerate 를 활용했다는 점입니다. 원래의 코드에서 L9 에 있는 insert() 의 호출은, 리스트의 길이에 비례하는 시간을 요합니다. (인자로 주어진 c 가 리스트에서 처음 발견되는 위치를 찾는데, 그러기 위해서 리스트의 원소를 Python 내부에서 앞에서부터 하나씩 하나씩 검사해야 하기 때문입니다.) 따라서, 어차피 리스트 원소를 하나 하나 검사하면서 (원래 코드 L7 에서 시작하는 for 순환문에서) 대소 비교를 하고 있으니, 이 인덱스 또한 순환문이 스스로 처리할 수 있도록 함으로써 보기에도 좀 낫고 효율도 좀 나아지는 코드가 됩니다.

이것은, for i in range(L): 을 이용하는 순환문으로 바꾸어 쓸 수도 있는데, 그것은 직접 한번 해보시는 것이 (아주 쉬운 것이지만) 좋은 연습이 되리라고 생각합니다.

  • 이유찬
    감사합니다, 특히 return 부분은 앞으로 신경쓰도록 하겠습니다 ^^ 이유찬 2019.02.01 14:34
답변 쓰기
이 입력폼은 마크다운 문법을 지원합니다. 마크다운 가이드 를 참고하세요.