[파이썬 핵심 기초 다지기] 반복문, 흐름제어 & Comprehension

julian·2025년 2월 16일

python

목록 보기
7/74
post-thumbnail

📌 사용 환경

Python 3.10.2
conda 24.9.0
JupyterLab 4.2.5


  • 조건문: if, if~else, if~elif
  • 반복문: while, for
  • 흐름 제어: break, continue

지난 조건문(if)문에 이어 반복문이다.

반복문을 쓰는 경우는 두가지가 있다.

  1. 만약 apple을 100번 써야 하는 경우 print("apple")를 100번 쓸 수는 없다.
    그래서 이럴 때 반복문을 1~100번 반복하겠다. 라고 사용하는 것이다.

  2. 또, 지금까지 조건문(if)으로

x=10
if x[0]>10:
    ~

이런 구조였는데, 만약 list의 요소에 접근하는 경우에

x=[10, 20, 50, 70, 80]
if x[0] > 10:
    ~
if x[1] > 10:

이런식으로 쓰기에는 너무 효율이 떨어진다.

이러한 두 가지 경우에 반복문을 사용한다.

즉 반복문은 특정한 작업을 여러 번 되풀이해서 수행하고 싶은 경우 사용한다.
그리고 for와 while 두 반복문은 다음과 같은 경우로 나누어 사용한다.

  • for 문: 반복 횟수가 미리 정해져 있는 경우
  • while문: 반복 횟수가 정해져 있지 않지만, 조건이 명확한 경우

1. for문

  • for 문: 반복 횟수가 미리 정해져 있는 경우

for문의 구조는 다음과 같다.

for 변수 in 컬랙션 또는 range():  
		수행할 문장들  
		..  
		수행할 문장들  

컬렉션(str, list, tuple, set, dict)의 요소를 순서대로 반복하면서 명령을 실행한다.

1.1. range()

range() 함수는 파이썬 내장함수로, 슬라이싱과 비슷하다.
특정한 구간의 정수 열을 반복해서 생성하며, for 문에서 순환을 위한 용도로 사용된다.
range([초기값,][반복조건][,증가값]) 의 구조를 가진다.

a=range(0,10,1)  # 0부터 10 미만까지 1씩 증가
print(a, list(a))

print(list(range(10)))  # 초기값 디폴트: 0, 증가값 디폴트: 1
print(list(range(1,10,1)))
print(list(range(5,20,2)))
print(list(range(10,0,-1)))

# ✅ 출력 결과
# range(0, 10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# [5, 7, 9, 11, 13, 15, 17, 19]
# [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

1.2. for문()

  • for (새로운 변수) in range(반복 실행 횟수)
for i in range(1,11,1):
    print(i, end=" ")
print()

sum=0
for i in range(1, 11, 1):
    sum += i
print(sum)

sum=0
for i in range(1,21,1):
    if i%2==0:
        sum += i
        print(i, end=' ')
print("\n", sum)

# 짝수 합
sum=0
for i in range(1,101):
    if i%2==0:
        sum+=i
print(sum, "\n")

# 구구단 2단
DAN=2
for i in range(1,10):
    print("%d * %d = %d" %(DAN, i, DAN*i))

# ✅ 출력 결과
# 1 2 3 4 5 6 7 8 9 10 
# 55
# 2 4 6 8 10 12 14 16 18 20 
# 110
# 2550
# 2 * 1 = 2
# 2 * 2 = 4
# 2 * 3 = 6
# 2 * 4 = 8
# 2 * 5 = 10
# 2 * 6 = 12
# 2 * 7 = 14
# 2 * 8 = 16
# 2 * 9 = 18

2. 다중 for문

for문 안에 for문이 들어가는 것을 말한다.
이를 이용하여 구구단을 전부 출력할 수 있다.

for i in range(2,10):
    for j in range(1,10):
        print("%d * %d = %d" %(i,j,i*j))
    print()
    
# ✅ 출력 결과
# 2 * 1 = 2
# 2 * 2 = 4
# 2 * 3 = 6
# 2 * 4 = 8
# ...
# ...
# 9 * 6 = 54
# 9 * 7 = 63
# 9 * 8 = 72
# 9 * 9 = 81

3. for - collection(list, set, tuple, dic)

for (변수) in (순회할 리스트 이름):
	반복적으로 수행할 for 블럭

3.1. list

lst=[1,3,33,45,100]

for value in lst:
    print(value, end=' ')

# ✅ 출력 결과
# 1 3 33 45 100 

그냥 print(lst) 해도 나오긴 하지만, 하나하나 뽑아서 비교해 줄때가 필요하다.
for문을 쓰지 않으면 lst[0], lst[1] 이런 식으로 해야하는데,
하나하나 뽑을때 for문의 value로 들어가게 되어 비교가 가능하다.

print(lst, lst[0], lst[1])

for value in lst:
    if value > 15:
        print(value, end=' ')

# ✅ 출력 결과
# [1, 3, 33, 45, 100] 1 3
# 33 45 100 

3.2. set

st={1,2,3,4}
print(st)

for value in st:
	print(value, end=" ")
    
# ✅ 출력 결과
# {1, 2, 3, 4}
# 1 2 3 4

3.3. tuple

t=(1,2,3)
print(t)

for value in t:
	print(value, end=" ")
    
# ✅ 출력 결과
# (1, 2, 3)
# 1 2 3

3.4. ⭐ dic

dic는 가장 많이 쓰인다.

dict={"짱구":10, "맹구":20, "철수":50}
print(dict)
print(dict.keys())
print(dict.values())
print(dict.items())
print(dict["철수"])

# ✅ 출력 결과
# {'짱구': 10, '맹구': 20, '철수': 50}
# dict_keys(['짱구', '맹구', '철수'])
# dict_values([10, 20, 50])
# dict_items([('짱구', 10), ('맹구', 20), ('철수', 50)])
# 50

딕셔너리의 key 값만 뽑으려고 한다면, dictionary에 관한 글에서도 설명했듯이 바로 뽑을 수 없다.

keys(), values(), items()라는 딕셔너리 메서드를 사용하여 나온 값들은 리스트의 형태를 띄지만, 데이터 타입을 확인해보면 각각 dict_keys, dict_values, dict_items 라는 새로운 데이터 타입임을 알 수 있었다. 하지만 dict 객체는 값을 뽑을 수 없다.

따라서 각 값들을 가져오려면 형 변환이 필요했다.

하지만 이 for문을 사용하면 그 과정이 필요없어서 이런 경우에 사용된다.

key의 경우와 value의 경우는 다음과 같다.

for key in dict.keys():
    print(key, end=" ")

for value in dict.values():
	print(value, end=" ")

# ✅ 출력 결과
# 짱구 맹구 철수
# 10 20 50

심지어 items()함수는 리턴 값이 리스트 안에 튜플을 가진 형태였기에 인덱스를 이용해 위치를 찾아가서 해당 튜플을 다시 리스트로 형 변환하여 값을 가져오는 굉장히 복잡한 과정을 가졌었는데, for문을 사용하면 이 과정이 필요 없어진다.

for key, value in dict.items():
    print("{}의 점수는:{}".format(key, value))

# ✅ 출력 결과
# 짱구의 점수는:10
# 맹구의 점수는:20
# 철수의 점수는:50

4. while문

  • 반복 횟수가 정해져 있지 않지만, 조건이 명확한 경우.
  • while 문 조건이 참인 동안에 while문 아래 문장이 반복된다.
while 조건식:
    수행할 문장들
    ...
    수행할 문장들

for 문은 수치 반복이 대부분인데, while 문은 조금 다르다.

while 문은 예를 들어 화면보호기가 계속 켜져있다가 마우스나 키보드의 입력을 받으면 꺼지는 것을 생각할 수 있다.

사실 파이썬에서는 그렇게 많이 사용하지 않지만, while문을 많이 쓰는 언어들이 있다. 예를들어 DB 연동하는 프로그램에서 많이 사용한다. 데이터를 가져오는데 행마다 커서(포인터)를 위치시키고 행 단위로 데이터가 있다면 가져오고 없으면 while문을 끝내는 형식이다.

따라서 이 while문은 '아~ 이래서 잘 안쓰구나' 하는 것을 깨달으면 된다.

반복문은 반드시 start가 있어야 한다.

num=1
while num <= 5:
    print(num, end=" ")
    num += 1

# for 문으로 쓸 경우
for numnum in range(1, 6):
    print(numnum, end=" ")
    
# ✅ 출력 결과
# 1 2 3 4 5 
# 1 2 3 4 5 

while문을 for문으로, for문을 while문으로 바꾸는 연습도 이렇게 해주면 좋다.
1~10까지의 숫자 중에서 홀수만 출력하며 whle문 안에 if문을 사용해보자.

num2=1
while num2 <= 10:
    if num2 % 2 != 0:
        print(num2, end=" ")
    num2 += 1
    
# for문으로는
for num2num2 in range(1, 11, 2):
    print(num2num2, end=" ")
    
# ✅ 출력 결과
# 1 3 5 7 9 
# 1 3 5 7 9 

4.1. 컬렉션

컬렉션 자료형을 for문을 이용해 뽑는 경우가 많은데(for in my_list 이런식으로 컬렉션을 했었는데) while문도 가능하다.
list의 경우로 살펴보자.

num=[10, 20, 30, 40, 50]

for n in num:
    print(n, end=" ")
    
# ✅ 출력 결과
# 10 20 30 40 50 

for문을 이용하면 이렇게 되었는데, 그렇다면 while문을 사용한다면?

i=0
while i < len(num):
    print(num[i], end=" ")
    i += 1

# ✅ 출력 결과
# 10 20 30 40 50 

물론 아래와 같이 for문의 인덱싱을 사용해도 되지만, 컬렉션 자료형을 사용하는게 더 편하다.

for i in range(0, len(num), 1):
    print(num[i], end=" ")

# ✅ 출력 결과
# 10 20 30 40 50 

5. 흐름 제어

  • break, continue
    break를 사용하는 경우가 더 많다.
    for문과 while문 둘 다 사용 가능하다.

5.1. break

  • break: 반복문에서 break 문장을 만나면 반복문을 빠져 나간다.

break문은 강제로 반복문을 빠져 나가야 할때 사용한다.

앞서 말한 DB의 설명을 어이서 하자면 while문을 돌다가 특정 조건을 찾았을때 더이상 데이터를 찾을 필요가 없다.
그렇다면 끝내면 되는데, 이때 사용하는 것이 break다.

for문에서의 break를 사용하는 경우를 살펴보자.

# for문
for i in range(1, 11):
    if i==5:
        break
    print(i, end=" ")
    
# while문
count=1
while count <= 20:
    if count == 5:
        break
    print(count, end=" ")
    count += 1
    
# ✅ 출력 결과
# 1 2 3 4
# 1 2 3 4

5.2. continue

반복문의 맨 처음(조건문)으로 다시 돌아간다.
루프를 빠져나오지 않고 continue 아래의 문장만을 건너뛰는 역할을 한다.

즉 계속 반복하고 이 반복을 유지해야 하는데, 특정 부분만 반복하지 않아야 하는 부분이 있어서 이를 건너뛰어야 할 때, continue를 사용한다.

for문에서 사용하는 경우는 다음과 같다.

# for문
for i in range(1,11):
    if i==5:
        continue
    print(i, end=" ")

# while문
count=0
while count < 10:
    count += 1
    if count == 5:
        continue
    print(count, end=" ")

# ✅ 출력 결과
# 1 2 3 4 6 7 8 9 10 
# 1 2 3 4 6 7 8 9 10 

조금 응용해보자.

# 과일 가격 설정
apple_price = 1000
pear_price = 2000
strawberry_price = 3000

# 초기 설정
money = 10000
apple_count = 0
pear_count = 0
strawberry_count = 0

while True:
    print("1번: 사과 (1000원)")
    print("2번: 배 (2000원)")
    print("3번: 딸기 (3000원)")
    
    # 사용자로부터 입력 받기
    choice = input("구매할 과일의 번호를 입력하세요 (그만하려면 '그만'을 입력하세요): ")

    # '그만' 입력시 쇼핑 종료
    if choice == '그만':
        break

    # 선택한 과일에 따른 처리
    if choice == '1':
        if money >= apple_price:
            money -= apple_price
            apple_count += 1
            print(f"사과 1개 구매, 남은돈 {money}원")
        else:
            print("돈이 부족합니다. 사과를 구매할 수 없습니다.")
    
    elif choice == '2':
        if money >= pear_price:
            money -= pear_price
            pear_count += 1
            print(f"배 1개 구매, 남은돈 {money}원")
        else:
            print("돈이 부족합니다. 배를 구매할 수 없습니다.")
    
    elif choice == '3':
        if money >= strawberry_price:
            money -= strawberry_price
            strawberry_count += 1
            print(f"딸기 1개 구매, 남은돈 {money}원")
        else:
            print("돈이 부족합니다. 딸기를 구매할 수 없습니다.")
    
    # 돈이 부족할 때 쇼핑을 계속할지 여부 묻기
    if money < min(apple_price, pear_price, strawberry_price):
        print("돈이 부족하여 더 이상 구매할 수 없습니다.")
        break
    
    # 쇼핑 계속 여부 묻기
    continue_shopping = input("계속 쇼핑을 하시겠습니까? (예/아니오): ")
    if continue_shopping.lower() != '예':
        break

# 쇼핑 종료 후 쇼핑 내역 출력
print("\n쇼핑이 종료되었습니다. 구매한 과일은 다음과 같습니다:")
print(f"사과 {apple_count}개")
print(f"배 {pear_count}개")
print(f"딸기 {strawberry_count}개")
print(f"최종 남은 돈: {money}원")

# ✅ 출력 결과
# 1번: 사과 (1000원)
# 2번: 배 (2000원)
# 3번: 딸기 (3000원)
# 구매할 과일의 번호를 입력하세요 (그만하려면 '그만'을 입력하세요):  3
# 딸기 1개 구매, 남은돈 7000원
# 계속 쇼핑을 하시겠습니까? (예/아니오):  예
# 1번: 사과 (1000원)
# 2번: 배 (2000원)
# 3번: 딸기 (3000원)
# 구매할 과일의 번호를 입력하세요 (그만하려면 '그만'을 입력하세요):  3
# 딸기 1개 구매, 남은돈 4000원
# 계속 쇼핑을 하시겠습니까? (예/아니오):  예
# 1번: 사과 (1000원)
# 2번: 배 (2000원)
# 3번: 딸기 (3000원)
# 구매할 과일의 번호를 입력하세요 (그만하려면 '그만'을 입력하세요):  3
# 딸기 1개 구매, 남은돈 1000원
# 계속 쇼핑을 하시겠습니까? (예/아니오):  예
# 1번: 사과 (1000원)
# 2번: 배 (2000원)
# 3번: 딸기 (3000원)
# 구매할 과일의 번호를 입력하세요 (그만하려면 '그만'을 입력하세요):  1
# 사과 1개 구매, 남은돈 0원
# 돈이 부족하여 더 이상 구매할 수 없습니다.

# 쇼핑이 종료되었습니다. 구매한 과일은 다음과 같습니다:
# 사과 1개
# 배 0개
# 딸기 3개
# 최종 남은 돈: 0원

⭐ while문에서 continue 문을 사용할때 주의해야한다.
만약 다음과 같을때 문제가 일어난다.
(아래 코드는 실행하지 말자)

countcount=1
while countcount < 10:
    if countcount==5:
        continue
    print(countcount, end=" ")
    countcount += 1

이렇게 사용하면 5를 만났을때 그냥 건너뛰어서 증감이 일어나지 않고, countcount가 5를 유지하며 다시 위로 올라가서 while문을 만나서 if 문에 걸리는 무한 루프를 돌게 되는 문제가 일어날 수 있다.

6. ⭐ Comprehension

여태까지 계속 반복했던 것을 보면 구조가
for문을 돌리면서 if문이 들어가고, while문을 돌리면서 if문이 들어가고, 또는 연산을 해주고 계속해서 이런 형식이었다.
이런 구조를 실제로 계속해서 사용해야 하니까 이걸 돕는 컴프리헨션이라는 것이 있다.

list, set, dictionary등 Collection 타입을 생성하기 위한 간결하고 효율적인 방법으로 작성한다.
튜플은 값을 변경 못하니까 list와 set, dictionary 형식을 사용한다.
하지만 dictionary는 조금 복잡하니까 잘 안쓰고 거의 lsit를 많이 사용한다.

구조는 이와 같다.

  • list: [식 for 변수 in 리스트 if 조건문]
  • set: {식 for 변수 in 세트 if 조건문}
  • dictionary: {키:값 for 변수 in 딕셔너리 if 조건문}
for i in range(10):  
    print(i, end=' ' )  

result=[]  
for i in range(10):  
    result.append(i)  

이런 것을 아래와 같이 사용하는 것이다.
i for i in range(10)

6.1. list

  • [식 for 변수 in 리스트 if 조건문]
result=[]
for i in range(10):
    result.append(i)
print(result)

# comprehension을 이용하면
result2=[i for i in range(10)]
print(result2)

# ✅ 출력 결과
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • list를 직접 이용하는 경우
result=[]
my_lst=[10,20,30,40,50]

for i in my_lst:
    i *= 10
    result.append(i)
print(result)

# comprehension
result2=[i*10 for i in my_lst]
print(result2)

# ✅ 출력 결과
# [100, 200, 300, 400, 500]
# [100, 200, 300, 400, 500]

⭐ 참고

if~else 문 까지 사용하면 [식 if 조건문 else 실행문 for 변수 in 리스트] 이와 같은데,
이렇게 까지 진행하면 오히려 더 복잡하고 가독성이 떨어질 수 있다.

result=[]
my_lst=[1,2,3,4,5]

for i in my_lst:
    if i > 2:
        i*=3
    else:
        i=0
    result.append(i)

print(result)

# comprehension
result2=[i*3 if i>2 else i*100 for i in my_lst]
print(result2)

# ✅ 출력 결과
# [0, 0, 9, 12, 15]
# [100, 200, 9, 12, 15]

6.2. dictionary

  • {키:값 for 변수 in 딕셔너리 if 조건식}
dict={}
for i in range(5):
    dic[i]=i**2
print(dict)

#comprehension
my_dict={i:i**2 for i in range(5)}
print(my_dict)

# ✅ 출력 결과
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

6.3. set

  • {식 for 변수 in 셋 if 조건식}
st=set()
for i in range(1, 11):
    if i%2==0:
        st.add(i)
print(st)

# comprehension
my_st={i for i in range(1,11) if i%2==0}
print(my_st)

# ✅ 출력 결과
# {2, 4, 6, 8, 10}
# {2, 4, 6, 8, 10}

💪 퀴즈

Q1. 다음 코드의 실행 결과를 예측하라.

sum = 0
for i in range(1, 11):
    if i % 2 == 0:
        sum += i
print(sum)

A1. 30(2+4+6+8+10)

Q2. 다음 코드의 실행 결과를 예측하라.

coffee = 5
money = 5000

while money >= 1000:
    coffee -= 1
    money -= 1000
    print(f"커피를 제공합니다. 남은 커피: {coffee}, 남은 돈: {money}")
    if coffee == 0:
        print("커피가 다 떨어졌습니다. 판매를 중지합니다.")
        break

A2. 커피를 제공합니다. 남은 커피: 4, 남은 돈: 4000
커피를 제공합니다. 남은 커피: 3, 남은 돈: 3000
커피를 제공합니다. 남은 커피: 2, 남은 돈: 2000
커피를 제공합니다. 남은 커피: 1, 남은 돈: 1000
커피를 제공합니다. 남은 커피: 0, 남은 돈: 0
커피가 다 떨어졌습니다. 판매를 중지합니다.

Q3. 다음 코드의 실행 결과를 예측하라.

for i in range(1, 11):
    if i == 5:
        continue
    print(i, end=" ")

A3. 1 2 3 4 6 7 8 9 10

Q4. 다음 코드의 실행 결과를 예측하라.

for i in range(1, 11):
    if i == 6:
        break
    print(i, end=" ")

A4. 1 2 3 4 5

Q5. 다음 코드의 실행 결과를 예측하라.

numbers = [1, 2, 3, 4, 5]
result = 0
for i in numbers:
    result += i * 2
print(result)

A5. 30(2+4+6+8+10)

Q6. 다음 코드의 실행 결과를 예측하라.

count = 0
for i in range(1, 11):
    for j in range(1, 11):
        if i * j > 50:
            count += 1
print(count)

A6. 19((69)+(610)+(78)+(79)+(710)+(87)+(88)+(89)+(810)+(96)+(97)+(98)+(99)+(910)+(106)+(107)+(108)+(109)+(10*10))

Q7. 다음 코드의 실행 결과를 예측하라.

numbers = [5, 3, 8, 6, 7]
max_num = numbers[0]
for num in numbers:
    if num > max_num:
        max_num = num
print(max_num)

A7. 8

Q8. 다음 코드의 실행 결과를 예측하라.

fruits = ["apple", "banana", "orange", "pear"]
result = ""
for i in words:
    if len(i) > 5:
        result += i[0]
print(result)

A8. bc

Q9. 다음 코드의 실행 결과를 예측하라.

numbers = [3, 5, 7, 9, 11, 13, 15]
result = 0
for i in range(len(numbers)):
    if i % 2 == 0:
        result += numbers[i]
    else:
        result -= numbers[i]
print(result)

A9. 9(3-5+7-9+11-13+15)

profile
AI Model Developer

0개의 댓글