PY4E Ch.5 Loops and Iterations

nalimeitb·2025년 4월 16일

PY4E

목록 보기
5/10

PY4E Ch.5 Loops and Iterations

반복은 4가지 기본 패턴 중 마지막이다.
이 패턴으로 하여금 컴퓨터가 많은 일을 할 수 있게끔 한다.
컴퓨터는 이런 집요함이 있고 또, 이런것을 굉장히 잘한다.

While Loop(Indefinite Loop)

While Loop는 기능적으로 if문과 비슷하다.
시작부분에 if문 처럼 참/거짓으로 답을 가려낼 수 있는 질문이 주어진다.
그 뒤에 콜론이 있고 들여쓰기 된 코드블럭이 있다.
그 뒤에 내어쓰기를 하면 이 루프가 어디서 끝나는지 결정된다.

루프를 실행해서 시작부분이 참이라면,
그 아래 코드를 실행하고 거짓이라면 해당 루프를 건너 뛴다.

if문과 차이점

if문과 작동방식의 다른 점은
코드를 한번 실행한 후에 반응에 있다.

예를 들어 while 루프의 경우는 한번 돌고나면
제일 위로 올라가서 같은 질문을 한번 더 한다는 점이다.

반복 변수

그래서 여기서 나타나는 특별한 while 루프안의
변수가 하나 있는데, 이를 '반복 변수'라고 한다.

이 반복변수를 통해 더욱 치밀하게 설계할 수 있다.

위 슬라이드에서는 n에 해당하는 것이 반복변수인데, 이 변수의 값을 변화시켜 루프를 실행시키되 무한루프에 빠지지 않도록 할 수 있다.

반복변수 n을 신중하게 설계하고
while 루프의 특성을 고려하여,
루프를 빠져 나올 수 있는 하나의 장치처럼 사용하는 것이다.

무한 루프

반복변수를 신중하게 사용하지 못하면,
질문의 값이 바뀌지 않기 때문에
무한루프에 빠지게 될 수 있다.
(이러면 컴퓨터 배터리가 다 닳아버리거나,
마우스 커서가 로딩중이라고 표시되거나,
또는 컴퓨터에서 필요한 자원을 여기서 쓰게 된다.)

Zero Trip

또, 절대 실행되지 않는 루프가 있을 수도 있다.
왜냐하면 질문에 대한 값이 항상 거짓이면 건너뛰기 때문이다.

위 예시에서는 n = 0 이고 질문이 0과 비교를 했다는 점이 특별하다. 0과 비교를 한다는 점에서 이를 'Zero Trip'이라고도 한다.

Breaking Out of a Loop(루프 제어 구문)

반복변수를 치밀하게 설계하여 무한루프에 빠지지 않게 하는 방법도 있지만, 루프를 벗어나는 몇가지 방법이 더 있다.

Break문

break는 루프 블럭의 다음 줄로 이동시킨다.
이 개념을 마치 초공간 점프라고 생각해도 좋다.
건너뛸 부분에 if문이 몇백줄 있을 수도,
그 사이에 온갖 다른 일들이 있을 수 있다.

중요한 점은 break 구문을 만나는 순간
그 아래 얼마나 많은 것이 있던 간에 루프를 나가버린다는 점이다.

Continue문

continue는 또 다른 루프 제어 구문이다.
하지만, break 와는 조금 다르게 작동하는 부분이 있다.

break는 루프에서 아예 이탈시켜버리는 반면, continue는 이번 회차의 실행을 멈추고 스킵시킨다.
여기서 스킵시킨다는 표현은 중간에 멈추가 다시 맨위로 올라가는 다는 것이다.

Indefinite Loop

while 문으로 이루어진 반복문은 불확정 루프라고 부르기도 한다. 그 이유는 이러한 루프가 break를 만나거나 어떠한 값이 거짓이 되기 전까지 계속해서 실행될 수 있기 때문이다.

어쩌면, 코드의 길이가 길어지고 종료조건이 복잡해지면, 코드가 정말 종료할 수 있는지 확정적이라고 단정할 수 없다.

그렇기 때문에 while 루프를 이용해 많은 것을 할 수 있지만, 대부분 반복문은 definite loop를 활용하고자 한다.

For Loop(Definite Loops)

유한루프는 "for" 키워드를 사용한다.
유한루프의 개념은 어떤 !집합의 원소들!에 대해서 반복문을 실행하는 것이다.

집합의 원소는 루프가 실행되는 집합에 따라 유한번 실행된다.

이러한 루프를 선호한다.
코드를 만들기도 쉽고
반복변수를 따로 처리할 필요도 없다.

for 루프는 반복변수를 설계하는 매커니즘을 포함하고 있다.
유한루프는 집합의 원소를 통해 반복한다.
for 키워드와 in 키워드를 확인할 수 있는데,
여기서 i가 반복변수로 선언이 된다.

i는 선언문과 같다.
i가 루프의 매 iteration에서 값이 변하는 것이다.

그렇다면 집합의 원소들은 항상 꼭 숫자여야 하는가?
꼭 숫자 리스트여야 하는가?
꼭 그럴 필요 없다.
for문을 이용해 반복적으로 읽을 수 있는 것은 많다.

For VS While

for 루프는 만약 while 루프였다면
개별구문 몇개가 했어야 할 일들을 한번에 할 수 있다.

예를 들어보자면,
먼저 루프가 몇번 실행할지 결정한다.
그래서 루프가 끝났는지 물어보는 질문에 답해
어떤 방향으로 실행할지 결정한다.
그리고 i 값을 바꾸어 반복변수를 관리한다.
또 다시 돌아갔을 때, 초기화도 한다.

while루프로 생각해보면,
n = 5, 과 같은 선언문
while n > 0, 과 같은 조건문
n = n - 1, 과 같은 반복 변수 처리문
이런 코드가 필요했다.

하지만 for 문에서는 그럴 필요가 없다.
for 루프에서는 그저
for i in [5, 4, 3, 2, 1]
이렇게 해주면 단 한줄로 코드가 처리한다.

In

in은 수학의 집합론을 연상시킨다.
이를 함수의 원소라고 말하는 것이나,
각각의 원소에 대하여 라고 말하는 점

순서가 있는 집합(시퀀스)의 각 원소 5, 4, 3, 2, 1에 대하여 한번씩 실행하여 반복한다.
반복변수 i의 값을 이 집합의 원소로 설정하고
루프를 실행시키는 것이 수학적 사고를 하는 사람들에게 좋은 개념을 연상시킨다.

Loop Idioms : What We Do in Loops

우리가 자주 접하는 문제들 중에서
예를 들어 집합의 원소에서 문자열 또는 숫자에서 가장 크거나 가장 작은 것을 찾거나 또는 그 원소들을 모두 다하고 싶거나 할때 사용하는
루프들의 패턴이 있을 수 있다.

반복문을 통해 각각의 원소를 검토하고,
각 원소에게 무언가 하라고 할 수 있다.
그렇게 해서 모든 원소를 더하게끔 할 수 있다.

**우리가 사용할 패턴은
어떤 덩어리에 포함된 각 요소에 대해
한번씩 실행되는 루프를 가지고

처음에 무언가 설정한 후,
각 요소에 대해 무언가 실행하고,
마지막에 결산을 얻는 방식이다.

루프가 시작하기 전에
루프가 실행되는 동안에는 무엇을 할지
또 이를 어떻게 사용할 수 있는지
프로그램처럼 생각해보는 것이 중요하다.**

Finding the Largest Value

최대값은 어떻게 찾을 수 있는가?
컴퓨터의 입장해서 생각해보라.
컴퓨터는 무언가 차례대로 해서 가장 큰 수로 답을 내놓을 것이다.

변수를 하나 따로 만들어서
이를 리스트에서 본 것 중에 가장 큰 값에 넣는 것이다.

그리고 다음 숫자를 보고,
초기값과 비교해 더 크다면,
그 큰 값을 변수에 넣어 저장한다.

! 이 저장하는 행위는 우리는 기억해야 한다.

여기서 한가지 아이디어를 얻을 수 있는데,
루프에서 무언가 실행하는 동안
실제 답을 가르키지는 않지만,
루프가 끝나면 답을 얻게되는 아이디어이다.

루프의 실행 전,
루프 실행 중,
루프 실행 후 단계가 있다는 것을 꼭 기억하라

이 예제가 알려주는 개념은 루프 시작 전 설정해야할 것과 루프를 통해 반복적으로 실행해야 하는 것, 그리고 마지막에 출력할 것을 설계하는 방법이다.

Counting in a Loop

위에서 설명했듯이

루프 시작 전 설정해야 하는 것,
루프 실행 중에 반복적으로 행해야 하는 것,
그리고 마지막에 결국 출력해내야 하는 것
이 세가지 관점으로 이 문제를 바라보겠다.

루프 시작 전에는 카운트를 하는 변수를 하나 도입한다.
그리고, 반복적으로 실행해야하는 작업은 루프를 실행할 때 마다, 카운트 변수에 하나씩 더해주는 것이다.
그리고 마지막으로 결국 출력해야하는 것은 다 더해진 카운트 변수의 값을 출력해야한다.

Summing in a Loop

합계는 어떻게 코드를 설계해야 할까?

시작 전, 합계를 넣을 변수를 하나 만들고 0으로 초기화해야할 것이다.
루프 실행 중에는, 합계 변수에 루프가 실행될 때 마다 원소의 값을 추가해줘야 한다.
마지막으로 결국 출력해야하는 것은 합계 변수에 다 더하고 난 합계 변수의 값을 출력해야한다.

Finding the Average in a Loop

평균은 합계 나누기 개수로 구해지기 때문에,
앞전에 기억을 떠올려 합계변수와 카운트변수를 도입하고 메트릭을 적용해 마지막에 출력하는 값만 합계 / 카운트로 출력해주도록 수정하면 된다.

Filtering in a Loop

위 문제에서는 값이 20 이상인 값을 필터링하는 작업이다.
루프 시작 전에 따로 설정해줘야하는 것이 있을까?
없을 것 같다.
루프 실행 중에는 각 원소가 20보다 큰지 확인해줘야할 것이다. 그리고 20보다 클 때 마다, 출력해주면 된다.

필터링은 루프안에 조건문을 넣어 큰 집합에서 무엇을 선택하거나 탐색하는 것이 핵심 아이디어이다.

Boolean Variable

불 자료형은 참과 거짓 두 가지 값만을 갖는 자료형이다.

특정 값이 존재하는 지 알고싶을 때
조건문과 불형 변수를 이용하여 판단하기 쉽다.

위 코드에서는 루프 실행 전에, found라는 변수를 통해 거짓으로 초기화하여 찾고자하는 것이 맞는지 파악할 수 있도록 했다.
루프 실행 중에는, 특정한 값과 각 원소의 값이 일치 하는지 조건문을 통해 판단하고 만약 True 값을 갖는다면 출력하도록 했다.
루프가 끝난 후에는, After를 출력하여 모든 원소에 대하여 일치여부를 판단했음을 확인시켜준다.

How to Find the Smallest Value

최대값 찾기 코드에서 확인했듯이,
루프 실행 전 가장 큰 값을 갖도록 하는 변수에
비교를 위해 음수를 넣어 초기화 했던 것을 기억할 것이다.

하지만, 최솟값은 어떨까?

시퀀스의 원소들의 범위를 미리 알지 못하기 때문에 비교하고자 하는 값에 비해 충분히 큰 값을 대입하여 설정하는 것은 무리가 있어보인다.

None

이때, 우리의 문제를 효과적으로 해결하기 위해서
None 자료형을 알아야 한다.
None 자료형은 하나의 값만을 가지는 특별한 자료형이다.
None 은 상수이다.

차이점은 None을 저장했는지 확인할 수 있다는 점이다.
None은 공백을 나타내기 위해 자주 쓰인다.
None이 비존재를 의미하는 것은 아니다!

is / is not Operators

is VS ==

얼핏 보면, is 연산자와 == 연산자는 같다고 생각할 수 있다.
두 개의 연산자는 유사한 기능을 행한다.
하지만 is 연산자는 == 연산자보다 강력하다.
강력하다는 것은 무엇을 의미하는 가?

예를 들어 보자면,
0 == 0.0 을 적으면 참을 반환하지만,
0 is 0.0 을 적으면 거짓을 반환한다.

어떤 차이가 있는 걸까?
0과 0.0은 값은 같지만 자료형이 다르다.
즉, is 연산자는 값과 자료형 두 가지의 동등성을 요구한다.
== 연산자는 값의 동등성만을 요구한다.

is 연산자는 매우 강력한 연산자이기 때문에,
남용하지 않을 것을 권고한다.

만약 숫자나 문자열을 다루고 있으면
== 연산자만을 사용하는 것으로 충분하다.

is 연산자는 boolean 또는 None 자료형이 있을 때에만 사용하는 것을 권고한다.

in not 연산자 역시 is와 유사하다.
어떤 것은 is not None 이라고 적거나
is not False라고 적으면 된다.

실습

sum = 0
count = 0
avg = 0

while True :
    a= input("Enter a number : ")
    if a == 'done' :
        break
    try :
        a = float(a)
        sum = sum + a
        count = count + 1

    except :
        print("Invalid input")



avg = sum / count
print(sum, count, avg)

Quiz

2번 문항을 두번이나 틀렸다.
흠...

사실 처음 보자마자 든 생각은
내가 아는 조건문의 개념이 틀렸는가?
동일한 위계에 있는 if와 elif 는
그 조건(질문)이 겹치지도 빠지지도 않아야 한다고 생각했다.

그런데 나는 단순히 두 조건만 비교했던 것 같다.
내가 말한 두 조건이 겹치지도 빠지지도 않는 상태여야 한다는 것은 결국엔, if 문 덩어리, elif문 덩어리 두개가 모순이어야 한다는 점이었다.

위 문제의 경우에서는 if 문 덩어리에서 x 값에 1을 더해준다. 그렇게 하므로써, elif 문 덩어리와 모순을 갖는 지점이 생겨나도 if문 덩어리에서는 거짓이지만, elif 문 덩어리에서는 참인 값이 단 하나 10이 출력될 수 있다는 것이다.

연속된 오답 표기가 나를 조금 괴롭게 했지만,
뭐 어때 또 한번 깊게 생각해볼 만한 주제가 생겨 좋았고 다른 친구들은 어떻게 생각했는지 궁금하기도 하다.

0개의 댓글