221109 TIL

고먐미·2022년 11월 9일

이중 for 문에 대해..

만약 input = [3, 7, 5, 11, 6, 9, 1732] 라는 리스트가 있다.
이 때, 가장 큰 수는 무엇일까?
우리는 1732 가 가장 큰 수 인것을 바로 알 수 있다.
하지만 똑똑하면서 멍청한 컴퓨터는 바로 알 수 없다.
왜냐면.. 컴퓨터가 알아들을만한 로직이 없기 때문이다.

오늘은! 이 컴퓨터가 알아들을만한 로직을 세워보았다.

시작하기에 앞서 가장 큰 수를 뽑아낼 때 이중 for문을 사용하는 것은 효율적이지 않다. (일을 두번하는 느낌)
이를 염두해두고 로직을 세워보도록 하자.

input = [3, 7, 5, 11, 6, 9, 1732]


def find_max_num(array):
    for num in array:
        for compare_num in array:
            if num < compare_num:
                break
        else:
            return num


result = find_max_num(input)
print(result)

이중 for문을 통해 로직을 세웠고, 결과값은 1732가 나왔다.
그 이유에 대해 한번 알아보자.


일단 변수 numarray 를 집어넣었다. (여기서는 input, 이를 1번 for문이라고 하겠다.)
그 후, compare_num 에 다시 array를 집어넣었다. (이를 2번 for문이라고 하겠다.)
결국 numcompare_num 둘 다 array 인 것이다.


추가 설명

사실 이미 코드를 한 바퀴 돌았다.
한 바퀴 돌았다는게 어떤 의미냐면, input에서 print까지 쭉 훑었다는 의미이다.
그러니까 『input 이라는 리스트가 있군!』하며 제일 첫 줄인 input 부분을 인식하고 ,
함수 부분이 실행된다. 하지만 array에 아직 값이 들어가지 않았기 때문에 『array의 값이 없는데?』하고 함수의 결과값이 None 즉, 아무것도 아닌 상태?로 아래 코드로 내려간다.
그리고 result 에 함수 값을 넣는데, 이는 input 리스트를 array에 넣은 값이다. (아직 계산하지 않음)
이제 result 값을 출력하는데 애초에 함수에 계산된 값이 없었으니 다시 제일 처음 코드로 올라가 다시 시작하는 것이다.

결국 이렇게 한바퀴 돌고나서야 함수에 input 값을 넣고, 함수를 돌려보기 시작하며, 값이 나온것을 result에 넣고, 그 값을 출력한다는 뜻!

아무튼,
1번 for문이 시작되면 numarray의 첫 번째 값(3)을 넣고, 2번 for문을 시작한다.
2번 for문은 compare_numarray의 첫 번째 값(3)을 넣는다.
그 후 num 값이 compare_num보다 작으면 2번 for문을 멈춘다. (break)

지금은 numcompare_num의 값이 둘 다 3으로 num의 값이 compare_num의 값보다 작지 않기 때문에 넘어간다. (num < compare_numFlase기 때문인듯 하다)

그 다음 compare_numarray의 두 번째 값(7)을 넣는다.
num 값이 compare_num의 값보다 작다.
2번 for문을 멈춘다. (num < compare_numTrue고 이로인해 break가 실행)


2번 for문이 멈췄으면 다시 1번 for문으로 돌아온다.
이제 numarray의 두 번째 값(7)을 넣고, 2번 for문을 다시 시작한다.

이제부터 조금 빠르게 진행해보겠다.
num의 값은 7, compare_num의 값은 3 -> 2번 for문 진행
num의 값은 7, compare_num의 값은 7 -> 2번 for문 진행
num의 값은 7, compare_num의 값은 5 -> 2번 for문 진행
num의 값은 7, compare_num의 값은 11 -> 2번 for문 종료 (break)

2번 for문이 멈췄으니 다시 1번 for문으로 돌아가 num값을 재할당 해준다. (반복)


결국 1732라는 값이 가장 크므로 num에는 1732라는 값이 남게되고, 2번 for문은 끝까지 실행이 되었다. (비교를 계속 해도 1732라는 숫자보다 더 큰 수가 없기 때문)
그렇게 2번 for문이 전부 실행되었기 때문에 2번 for문의 else 구문이 실행된다. (for else 구문)

2번 for문의 else 구문은 return num
다시말해 num을 출력하라는 의미이다.

그렇기 때문에 마지막 num 값이였던 1732가 출력되고, 모든 for문이 종료된다.


덧붙여, input = [3, 7, 5, 11, 6, 9, 1732, ...]이라고 해도 뒤에 나오는 숫자들이 1732보다 낮다면 for else 구문이 실행되며(2번 for문이 종료되며), num 값이 1732로 출력된다.




그래서 좀 더 효율적인 방법은?

자, 그럼 좀 더 효율적인 방법에 대해 알아보자.

이번에도 역시 input = [3, 7, 5, 11, 6, 9, 1732] 라는 리스트를 사용한다.

이중 for문에서는 array의 첫 번째 숫자를 나머지 숫자들과 모두 비교한 후, 두 번째 숫자를 나머지 숫자들과 모두 비교하고, 세 번째 숫자를.....

설명하기도 귀찮을 정도로 비효율적인 방법을 사용했었다.

좀 더 효율적인 방법은 무엇이 있을까?

우리는 어떻게 1732 라는 숫자가 가장 크다는 것을 바로 알 수 있었을까?

바로 첫 번째 숫자부터 마지막 숫자까지 훑어보면서 계속해서 숫자를 비교해 가장 큰 수만 기억하는 방법을 사용했기 때문일것이다. (아님말고)

그렇다면 이제 이에대한 코드를 작성해보자.

input = [3, 7, 5, 11, 6, 9, 1732]


def find_max_num(array):
    max_num = array[0]
    for num in array:
        if num > max_num:
            max_num = num

    return max_num


result = find_max_num(input)
print(result)

일단, 이중 for문에서 했던 방식처럼 리스트를 만들고, 제일 높은 수를 찾아내는 함수를 만들었다.
그 후 result 라는 변수에 input을 넣고 함수를 돌린 결과값(result = find_max_num(input))을 넣어주어 result를 출력했다.

그렇다면 지금은 어떻게 코드가 구동되는지 하나씩 뜯어보도록 하자.


일단 max_num 이라는 변수에 array의 1번째 값을 넣었다. (리스트형이기 때문에 [0]이라고 쓴다)
그 후 for문을 통해 num 안에 array를 넣어주었다.
그렇게 되면 num 값은 array의 첫 번째 값(3)부터 마지막 값(1732)까지 차례대로 들어가게 된다.


이제 for문 안의 if문으로 num 값이 max_num보다 크다면! max_num 값을 num 값으로 바꿔준다.

처음에는 num 값이 3, max_num 값도 3이므로 num > max_numFalse이다.
결국 max_num의 값은 바뀌지 않았다.

그 다음에는 num 값이 array의 두 번째 값인 7이다.
이제 num값은 7, max_num값은 3이고, num > max_numTrue가 되며 max_num = num 이라는 코드가 실행된다.
결국 max_num의 값이 7로 변경되었다.

이번에도 조금 빠르게 진행해보자.
num 값은 5, max_num값은 7 -> 다음 array

이를 array의 마지막 값(1732)까지 반복한다.

profile
개념을 이해하고 다른사람에게도 알려줄 수 있는 개발자가 되고 싶어요..

1개의 댓글

comment-user-thumbnail
2022년 11월 10일

정리 너무 잘하신것같습니다
직접 결과값이 나오는 과정을 코드리뷰하심으로 금번 코드는 확실히 익히셨을것같아요!

답글 달기