파이썬으로 웹프로그램을 작성 시 프로그램의 흐름 제어 중에서 반복하는 방법에 대해서 알아보자. 반복을 의미하는 단어는 repeat와 literate가 있는데 프로그래밍에서 단순하게 반복만 하는 것보다는 약간씩 변화를 주는 경우가 많기에 repeat보다는 literate를 많이 사용한다. 한 바퀴 돌아와서 다시 시작한다는 의미로 루프(loop)를 만든다고 표현하기도 한다.
반복문
# 명령문을 여러번 입력해서 반복하기
print("안녕하세요?")
print("안녕하세요?")
print("안녕하세요?")
안녕하세요?
안녕하세요?
안녕하세요?
그런데 만약 3번이 아니라 천번이나 만 번이라면? 컴퓨터 입장에서 같은 작업을 천 번 만 번 반복하는 것은 별 것 아니지만 프로그래머 입장에서 같은 코드를 천 번 만 번 반복해서 적어줘야 한다면 복사 붙여 넣기를 활용한다고 하더라도 "내가 왜 이걸 하고 있지?"라는 허무감이 들 겁니다. 반복 입력이 비효율적인 또 다른 사례로는 반복 횟수가 미리 정해져 있지 않은 경우입니다. 예를 들어서 몇 번 반복할지를 사용자로부터 입력받는다면 어떻게 해야 할까요? 게다가 매번 다른 문구를 출력해야 한다면? 이런 다양한 흐름들을 효율적으로 구현하기 위해 반복문을 사용합니다.
여러 번 반복되는 루프(loop)를 만드는 방법은 for
과 while
두 가지가 있습니다. for
문과 while
문은 이론상으로는 서로 호환이 가능하지만 실제로는 용도가 약간 다릅니다.
for
문: 반복을 시작하기 전에 반복의 범위가 미리 결정되어있는 경우에 많이 사용합니다.while
문: 언제까지 반복을 해야하는 지에 대해 명확한 범위 대신 조건으로 주어진 경우에 많이 사용합니다.
print()
출력 옵션 조절
print()
함수는 기본적으로 출력 후에 줄바꿈을 덧붙이게 되어 있습니다. end=" "
를 사용하면 줄바꿈을 빈 칸 하나로 바꿔주기 때문에 한 줄에 여러 번 출력을 할 수 있습니다. 당연히 빈칸 대신에 원하는 문자열을 넣을 수도 있습니다. 반복문으로 여러 가지를 출력할 때 가독성을 높여줍니다.
# 기본
print("줄바꿈이") # print("줄바꿈이", end="\n")
print("있어요") # print("있어요", end="\n")
# end=" " 사용
print("아이템1", end=" ")
print("아이템2", end=" ")
print("아이템3")
# end="!" 사용
print("줄바꿈이", end="!")
print("없어요")
줄바꿈이
있어요
아이템1 아이템2 아이템3
줄바꿈이!없어요
여러 객체를 컴마로 구분해서 출력할 때는 사이에 빈칸이 자동으로 들어갑니다. 빈칸 대신에 sep = "*!?"
과 같이 원하는 문자열을 넣어줄 수 있습니다. sep
는 seperator의 약자입니다.
print("안녕", 123, "하세요?")
print("안녕", 123, "하세요?", sep="")
print("안녕", 123, "하세요?", sep="*!?")
안녕 123 하세요?
안녕123하세요?
안녕*!?123*!?하세요?
반복문 for
for
문의 일반적인 형태
for
문의 간단한 용법들은 앞에서 많이 봤기 때문에 여기서는 일반적인 형태를 먼저 살펴보겠습니다.
for 변수 in 이터러블-객체:
반복할 명령문들
else:
반복이 (break없이) 끝나면 실행될 명령문들
여기서 in
과 :
사이에는 반복에 사용할 수 있는(iterable, 이터러블) 객체가 들어갈 수 있습니다. 예를 들어서 int나 float 같은 숫자 자료형들의 객체는 들어갈 수 없고 list나 tuple 같은 컨테이너형의 객체들은 들어갈 수 있습니다. 정수 범위에 대해 반복을 할 때는 범위(range) 형의 객체를 만들어서 사용할 수 있습니다. 변수
에는 이터러블이 제공해주는 아이템들이 차례대로 대입됩니다.
이 변수를 루프 제어 변수(loop control variable)라고 부르기도 하고 아이템이 대입되는 대상이라는 의미에서 대상(target)이라고 부르기도 합니다.
# 어떤 객체가 iterable 한지 확인하는 방법
from collections.abc import Iterable
isinstance(1, Iterable)
False
isinstance([1, 2, 3], Iterable)
True
isinstance(range(3), Iterable)
True
매 루프마다 루프 제어 변수에 이 터러블(iterable)의 아이템들이 하나씩 대입됩니다. 다른 변수들과 동일한 방법으로 사용할 수 있으며 이름도 변수명 규칙에 따라 마음대로 지을 수 있습니다.
# for 예시
for i in [8, 3, 5]: # i에는 8, 3, 5이 순서대로 대입됩니다.
j = i * 10
print(j)
80
30
50
# 위의 for-절(clause)을 풀어 쓰면 아래와 같습니다.
i = 8
j = i * 10
print(j)
i = 3
j = i * 10
print(j)
i = 5
j = i * 10
print(j)
80
30
50
else
-절은 if
문에서도 그랬듯이 필수는 아니며 for
루프가 정상적으로 실행이 완료되었을 때만 실행됩니다. 만약 break
명령을 이용해서 for
루프가 일찍 종료되었을 때는 실행되지 않습니다.
# for-else
for i in [8, 3, 5]:
j = i * 10
print(j)
else:
print("끝났어요")
80
30
50
끝났어요
범위(range) 사용법
range()
함수를 이용해서 정수 범위(range)를 만들어낼 수 있습니다. 보통 for
문과 함께 사용됩니다.
type(range(5))
range
괄호 안에 3가지의 인수(argument)를 넣어서 범위를 조절할 수 있습니다.
range(시작, 종료, 스텝)
시작, 종료, 스텝의 의미는 슬라이싱과 비슷하지만 함수 괄호 안에서는 컴마(,
)로 구분합니다.
# 괄호 안에 숫자를 하나만 넣으면 종료입니다.
# 이때 시작은 0, 스텝은 1로 간주합니다.
for i in range(5):
print(i, end=" ")
0 1 2 3 4
# 괄호 안에 숫자를 두 개 넣으면 시작과 종료입니다.
# 스텝을 입력하지 않으면 1로 간주합니다.
for i in range(1, 6):
print(i, end=" ")
1 2 3 4 5
# 스텝을 이용하여 건너뛸 수 있습니다.
for i in range(1, 6, 2):
print(i, end=" ")
1 3 5
# 음수 스텝을 사용할 수도 있습니다.
for i in range(5, 0, -2):
print(i, end=" ")
5 3 1
# range도 당연히 변수에 대입할 수 있어요
r = range(3)
for i in r:
print(i, end=" ")
0 1 2
컨테이너와 함께 사용하기
for
문은 다양한 컨테이너와 함께 사용하기가 편리합니다.
# int는 이터러블(iterable)이 아니에요 'int' object is not iterable
for i in 1:
print(i)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [16], in <cell line: 2>()
1 # int는 이터러블(iterable)이 아니에요 'int' object is not iterable
----> 2 for i in 1:
3 print(i)
TypeError: 'int' object is not iterable
# 문자열과 함께 사용하기 이터러블(iterable)
for i in "안녕하세요?":
print(i)
안
녕
하
세
요
?
# end가 빈 문자열일 경우
for i in "안녕하세요?":
print(i, end="")
안녕하세요?
# 튜플과 함께 사용하기
for i in (5, 7, 3):
print(i)
5
7
3
# 사전 : key값만 출력됩니다.
for k in {"원주율": 3.141592, "중력": -9.8}:
print(k)
원주율
중력
# 사전 keys()
for k in {"원주율": 3.141592, "중력": -9.8}.keys():
print(k)
원주율
중력
# 사전 values()
for v in {"원주율": 3.141592, "중력": -9.8}.values():
print(v)
3.141592
-9.8
# 아이템의 자료형을 확인해봅시다
for i in {"원주율": 3.141592, "중력": -9.8}.items():
print(i)
('원주율', 3.141592)
('중력', -9.8)
for i in {"원주율": 3.141592, "중력": -9.8}.items():
print(type(i), i)
<class 'tuple'> ('원주율', 3.141592)
<class 'tuple'> ('중력', -9.8)
# 언팩을 할 수 있습니다.
for k, v in {"원주율": 3.141592, "중력": -9.8}.items():
print(f"{k} -> {v}")
원주율 -> 3.141592
중력 -> -9.8
# 언팩을 할 수 있습니다.
for k, v in {"원주율": 3.141592, "중력": -9.8}.items():
print("{0:<10}: {1:>12}".format(k, v))
# print(f"{k:<12 } | {v:>12}")
원주율 : 3.141592
중력 : -9.8
# 언팩을 할 수 있습니다.
for k, v in {"원주율": 3.141592, "중력": -9.8}.items():
print("keys:{0:<10} values:{1:>12}".format(k, v))
keys:원주율 values: 3.141592
keys:중력 values: -9.8
print("{0:<10} | {1:^10} | {2:>10}".format("Left", "Center", "Right"))
print("{0:<10} | {1:^10} | {2:>10}".format("Left", 123, "오른r"))
print("{0:<10} | {1:^10} | {2:>10}".format("Apple", "Banana", "800308"))
Left | Center | Right
Left | 123 | 오른r
Apple | Banana | 800308
print(f"{'Left':<10} | {'Center':^10} | {'Right':>10}")
print("{0:<10} | {1:^10} | {2:>10}".format("Left", 123, "r"))
print(f"{'Apple':<10} | {'Banana':!^10} | {'800308':@>10}")
Left | Center | Right
Left | 123 | r
Apple | !!Banana!! | @@@@800308
# 컨테이너에 들어있는 것이 뭔지 모르겠다 싶을 때는?
my_list = [{1, 2, 3}, (4, 5, 6)]
for i in my_list:
print(type(i))
# type을 출력해서 확인해봅시다.
<class 'set'>
<class 'tuple'>
my_list = [{1, 2, 3}, (4, 5, 6)]
s_1 = 0
s_2 = 0
for j in my_list:
if type(j) == set:
for i in j:
s_1 += i
print(j, s_1)
if type(j) == tuple:
for i in j:
s_2 += i
print(j, s_2)
{1, 2, 3} 6
(4, 5, 6) 15
my_list = [{1, 2, 3}, (4, 5, 6)]
s_1 = 0
s_2 = 0
for j in my_list:
if type(j) == set:
for i in j:
s_1 += i
print(j, s_1)
else:
for i in j:
s_2 += i
print(j, s_2)
{1, 2, 3} 6
(4, 5, 6) 15
my_list = [{1, 2, 3}, (4, 5, 6)]
s_1 = 0
s_2 = 0
for j in my_list:
if j == my_list[0]:
for i in j:
s_1 += i
print(j, s_1)
else :
for i in j:
s_2 += i
print(j, s_2)
{1, 2, 3} 6
(4, 5, 6) 15
반복문으로 리스트의 아이템 바꾸기
for
문 안에서 반복에 사용하는 리스트의 아이템을 바꾸려고 시도한다면 어떻게 될까요?
# 리스트의 아이템이 불변일 경우
my_list = [1, 2, 3]
for i in my_list:
i *= 10
print(i, end=" ")
# my_list의 아이템들은 바뀌었을까요?
my_list
10 20 30
[1, 2, 3]
# 리스트의 아이템이 불변일 경우
# 이유를 조사해봅시다
my_list = [1, 2, 3]
print(id(my_list[0]), id(my_list[1]), id(my_list[2]))
for i in my_list :
print("Before:", id(i), i)
i *= 10
print("After:", id(i), i)
print(id(my_list[0]), id(my_list[1]), id(my_list[2]))
2419494185264 2419494185296 2419494185328
Before: 2419494185264 1
After: 2419494185552 10
Before: 2419494185296 2
After: 2419494185872 20
Before: 2419494185328 3
After: 2419494186192 30
2419494185264 2419494185296 2419494185328
# 인덱스를 이용해서 변경가능합니다.
my_list = [1, 2, 3]
for i in my_list :
my_list[i-1] = i * 10
my_list
[10, 20, 30]
# 리스트의 아이템이 가변일 경우
my_list = [[1], [2], [3]]
for i in my_list:
i *= 2
# l의 아이템들은 바뀌었을까요?
my_list
# [[2], [4], [6]]으로 만들려면?
[[1, 1], [2, 2], [3, 3]]
my_list = [[1], [2], [3]]
for i in my_list:
i[0] *= 2
my_list
[[2], [4], [6]]
그렇다면 리스트의 불변 아이템들은 바꿀 수가 없는 걸까요?
# 인덱싱으로 바꿀 수 있습니다.
my_list = [100, 200, 300]
# my_list[0] *= 2
# my_list[1] *= 2
# my_list[2] *= 2
for i in range(len(my_list)):
my_list[i] *= 2
my_list
[200, 400, 600]
튜플의 아이템을 인덱싱으로 바꾸려고 시도해보면?
# 튜플은 불변자료형이므로 변경되지 않습니다.
t = (100, 200, 300)
for i in range(len(t)):
t[i] *= 2
t
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [40], in <cell line: 3>()
1 t = (100, 200, 300)
3 for i in range(len(t)):
----> 4 t[i] *= 2
5 t
TypeError: 'tuple' object does not support item assignment
[참고] 튜플의 아이템이 리스트일 경우는 for
문 안에서 변경할 수 있습니다.
t = ([100], [200], [300])
for i in t:
i[0] *= 2
t
([200], [400], [600])
t = ([100], [200], [300])
for i in range(len(t)):
t[i][0] *= 2
t
([200], [400], [600])
if
문과 함께 사용
반복문 안에서 if
문을 사용할 수 있습니다.
for num in range(6):
if (num % 2) == 0:
print(f"짝수: {num}")
else:
print(f"홀수: {num}")
짝수: 0
홀수: 1
짝수: 2
홀수: 3
짝수: 4
홀수: 5
당연히 if
문 안에서 for
문을 사용할 수도 있겠지요.
정수 하나를 입력받고 입력받은 숫자가 짝수이면 입력받은 숫자만큼 "안녕?"을 출력해봅시다.
user_input = int(input("짝수를 입력해주세요: "))
if (user_input % 2) == 0 :
for i in range(user_input):
print("안녕?", end=" ")
짝수를 입력해주세요: 8
안녕? 안녕? 안녕? 안녕? 안녕? 안녕? 안녕? 안녕?
[보충] else
는 for
와도 사용될 수 있고 if
와도 사용될 수 있습니다. 가까운 줄이 아니라 들여 쓰기가 같은 for
나 if
와 짝을 이뤄서 사용됩니다. 아래 예시에서는 else
가 들여쓰기가 같은 for
와 짝을 이루기 때문에 "홀수:"는 for 루프가
끝난 후에 한 번만 출력됩니다.
for num in range(6):
if num % 2 == 0:
print("짝수:", num)
else:
print("홀수:", num)
짝수: 0
짝수: 2
짝수: 4
홀수: 5
for num in range(6):
if num % 2 == 0:
print("짝수:", num)
else:
print("홀수:", num)
짝수: 0
홀수: 1
짝수: 2
홀수: 3
짝수: 4
홀수: 5
for문으로 리스트의 합 구하기
my_numbers = [3, 6, 1, 2]
my_sum = 0
for i in my_numbers:
my_sum += i
print("합은 :",my_sum, "입니다.")
합은 : 12 입니다.
my_list = [3, 6, 1, 2]
# 파이썬에서 리스트에 들어 있는 정수 원소들의 합을 구하는 함수
sum(my_numbers)
12
짝수의 합만 계산해봅시다.
my_numbers = [3, 6, 1, 2]
even_sum = 0
for i in my_numbers:
if i % 2 == 0 :
even_sum += i
print(f"짝수의 합은 {even_sum}입니다.")
짝수의 합은 8입니다.
이번에는 곱을 구해봅시다.
my_numbers = [3, 6, 1, 2]
my_product = 1
for i in my_numbers :
my_product *= i
print(my_product)
36
홀수들끼리만 곱한 값을 계산해봅시다.
my_numbers = [3, 6, 1, 2, 5]
odd_product = 1
for i in my_numbers:
if i % 2 == 1:
odd_product *= i
print(odd_product)
# 결과로 15이 나와야 합니다.
15
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
'수학과 코딩' 카테고리의 다른 글
파이썬(python) 소수(prime number)판별, BMI계산 등 여러 기본 문제 (0) | 2022.07.31 |
---|---|
파이썬[python] 반복문[for, while] 안에서 반복문 사용하기 (0) | 2022.07.30 |
파이썬(python) 조건문(if.elif, else) 사용 방법 정리 (0) | 2022.07.29 |
파이썬(python) 표현식과 문장의 뜻 불리언(boolean) 자료형 (0) | 2022.07.28 |
파이썬(python) 컨테이너(container)딕셔너리(dictionary) 총 정리 (0) | 2022.07.27 |
댓글