어떤 조건을 보고 코드를 수행하는 것을 분기문이라고 하고, 어떤 조건 하에서 반복적으로 코드를 수행하는 것을 반복문이라고 부른다.
일반적으로 프로그램은 명령어가 기술된 순서대로 순차 수행되는데 분기문과 반복문은 순차 수행의 흐름을 변화시키기 때문에 제어문이라고도 부른다.
파이썬에는 if, for, while, range 함수 등 몇 가지 제어 흐름을 제공한다.
1. Boolean
지난 1일차에서는 파이썬의 기본 자료형인 정수형, 실수형, 문자열을 배웠는데, 이 세 가지 자료형이 파이썬에서 주로 사용되긴 하지만 Boolean(불리언)도 알게 모르게 자주 사용되는 기본 자료형이다. 다만 Boolean은 다른 자료형과 달리 True 또는 False라는 값만 바인딩할 수 있다.
다음 코드에서 a와 b라는 변수는 각각 True와 False라는 값을 바인딩하고 있다. type() 내장 함수를 이용해 타입을 확인해보면 <class 'bool'>이 반환되는 것을 볼 수 있다.
참고로 True나 False는 파이썬의 예약어로 true나 false가 아니라 첫 글자를 대문자로 사용해야 한다.
>>> a = True
>>> type(a)
<class 'bool'>
>>> b = False
>>> type(b)
<class 'bool'>
>>>
Boolean이라는 자료형은 파이썬의 비교 연산자에서 많이 사용된다. 여기서 비교 연산자라는 것은 어떤 두 값을 비교하는 데 사용되는 연산자를 의미한다.
파이썬에서 사용되는 비교 연산자는 다음과 같이 분류한다.
[파이썬 비교 연산자]
파이썬의 비교 연산자는 비교 연산자를 기준으로 왼쪽과 오른쪽에 비교할 값이 존재한다.
다음코드에서 첫 번째 문장은 정수형 값인 3을 서로 비교하는 예이다.
첫 번째 문장의 결과를 보면 True가 반환된 것을 확인할 수 있는데, 비교 연산자를 기준으로 왼쪽에 있는 3과 오른쪽에 있는 3이 같은 값이기 때문이다.
두 번째 문장을 보면 반환값이 False인 것을 확인할 수 있는데, 이는 두 값이 같지 않다(!=)라고 했는데, 실제로는 같은 값이기 때문이다.
세 번째는 왼쪽의 3이 오른쪽의 3보다 작다(<)라고 했는데, 실제로는 작지 않기 때문에 이번에도 반환값이 False가 된다.
>>> 3 == 3
True
>>> 3 != 3
False
>>> 3 < 3
False
>>> 3 > 3
False
>>> 3 <= 3
True
>>> 3 >= 3
True
>>>
위 코드처럼 Boolean 자료형은 비교 연산자의 반환값으로 자주 사용되며 비교 연산자는 정수형뿐만 아니라 실수형과 문자열 자료형에도 그대로 적용할 수 있다.
다음 코드를 보면 mystock이라는 변수는 "Naver"라는 문자열을 바인딩하고 있다. 이 상태에서 mystock이 바인딩하는 문자열이 "Naver"와 같은지(==) 확인해 보면 반환값으로 True가 반환된 것을 확인할 수 있다.
>>> mystock = "Naver"
>>> mystock == "Naver"
True
>>>
다음 예제에서 확인할 수 있듯이 내장 함수 bool은 임의의 형식을 가진 객체를 부울 형식으로 변환하는 것으로, 0과 값이 비어있는 경우는 False이며 0을 제외한 모든 값은 True이다.
2. 논리 연산자
파이썬에서의 다음과 같이 논리 연산자는 논리곱을 의미하는 AND(&)가 있으며, 논리합을 의미하는 OR(|)가 있으며, 부정을 의미하는 NOT이 있으며, 논리 연산의 결과는 논리값으로 True 또는 False 이다.
[논리 연산자]
논리 연산자 |
의 미 |
AND |
논리 곱(AND) 연산을 수행한다. |
OR |
논리 합(OR) 연산을 수행한다. |
NOT |
논리 부정(NOT) 연산을 수행한다. |
① 논리곱(AND)은 입력되는 값이 모두 True일 때만 True를 산출하고 하나라도 False 이면
False를 산출한다.
② 논리합(OR)은 입력되는 값이 모두 False일 때만 False를 산출하고 하나라도 True이면 True
를 산출한다.
③ 논리 부정(NOT)은 입력되는 값이 True이면 False를 False가 입력되면 True를 산출한다.
이러한 논리 연산자는 논리적 판단 식을 세울 때 많이 사용한다.
>>> grade = 4.3
>>> register = 7
>>> (4.0 <= grade) and (register >= 5)
True
1행에서 True와 False를 가지고 논리곱 연산을 한다. 여기서는 두 값이 모두 참이 아니므로 False를 내보낸다. 3행에서는 False와 True를 가지고 논리합 연산을 하는데, 두 값 중에 참이 하나라도 있으므로 True를 내보낸다. 5행에서는 False를 부정하여 반대되는 값인 True를 내보낸다. 7행에서는 '4 > 5'에서 5가 더 크므로 False, '104 < 311.4'에서는 311.4가 더 크므로 True를 내보낸다. 결과적으로 'False and True'가 되는 것이며 이는 False가 되는 것이다.
3. 조건문(Condition Statements)
조건문이란, 말 그대로 조건의 결과에 따라서 실행되는 문장이 결정되며, 파이썬에서의 조건문은 if문으로, 이 if문을 사용하면 조건식이 참(True)이냐 거짓(False)이냐에 따라 실행되는 문장을 다르게 만들 수 있다.
[형식]
위 형식을 보면 조건식이 참(True)과 거짓(False)으로 나뉘는데 주로 논리 연산자나 산술 연산자 등이 많이 쓰인다.
예를 들어, '만약에 변수 a의 값이 5보다 클 경우~'라는 조건을 만들어주고 싶으면 'if a > 5:'라고 써주면 된다.
주의할 점은, 조건식 뒤에 반드시 콜론(:)을 적어 주어야하며, 파이썬은 괄호로 묶는 다른 언어와는 다르게 들여쓰기로 영역을 구분한다.
즉, if문의 예로, 실생활에서 내일 친구의 집에 놀러가려고 하는데 만약 비가 온다면 놀러가지 못하는 것을 if문으로 표현하면 다음과 같다.
>>> price = 123
>>> if price >= 100:
print("Buy 10")
Buy 10
>>>
위 코드를 살펴보면 몇 가지 새로운 파이썬 문법을 볼 수 있다.
1) 조건문에는 if라는 키워드를 사용한다.
2) if 다음에는 '조건'이 존재하는데 이 조건이 참(True)이면 들여쓰기한 문장이 실행된다.
3) if 문의 끝에는 콜론(:)을 입력한다.
4) if 문의 조건이 참(True)일 때 실행되는 문장은 들여쓰기 해야 한다.
위 코드에서 첫 번째 문장이 실행되면 price라는 변수는 123이라는 정수값을 바인딩하게 된다.
두 번째 문장이 실행될 때 먼저 if 문의 조건에 해당하는 'price >= 100'에 대해 참인지 거짓인지가 판단된다. price 변수가 현재 바인딩하고 있는 값은 123이고, 이 값은 100보다 크거나 같으므로 조건식은 참이 된다.
if 문의 조건식이 참이므로 4칸의 공백으로 들여쓰기된 'print("Buy 10")'이라는 문장이 실행된다. 그래서 화면에 'Buy 10'이 출력된 것이다.
앞의 코드에서는 if 문의 조건식이 참일 때 들여쓰기된 한 줄의 코드(print("Buy 10"))만 실행됐다.
참고로 C/C++ 또는 자바 같은 프로그래밍 언어에서는 동시에 수행될 코드 블록을 { } 기호로 감싸서 표현하는 반면 파이썬에서는 들여쓰기를 통해 코드 블록을 표현한다.
>>> price = 123
>>> if price >= 100:
print("Buy 5")
print("Buy 6")
print("Buy 7")
Buy 5
Buy 6
Buy 7
>>>
파이썬이 아닌 다른 프로그래밍 언어를 사용한다면 이 부분이 처음에는 조금 어색할 수 있다. 그러나 시간이 지남에 따라 파이썬과 같이 들여쓰기를 통해 코드 블록을 표현하는 방식이 더 가독성 있는 코드를 작성하는 데 도움이 된다.
참고로 파이썬에서 들여쓰기는 키보드의 스페이스 바를 눌러서 같은 개수의 공백을 넣거나 탭을 사용해 들여쓰면 되는데, 보통 네 칸의 공백을 더 많이 사용한다.
[예제] 키보드로 총 평점을 입력받아 실행하는 프로그램
# coding: euc-kr
grade = float(input("총 평점을 입력해 주세요: "))
if grade >= 4.3:
print("당신은 장학금 수여 대상자 입니다.")
print("축하합니다.")
print("공부 열심히 하세요.")
[IF 문 형식]
if 조건 : 실행할 문장 |
또는
if 조건 : 조건이 참(True)일 경우 실행할 문장 else : 조건이 거짓(False)일 경우 실행할 문장 |
또는
if 조건 : 실행할 문장 #1 elif 조건 : 실행할 문장 #2 elif 조건 : 실행할 문장 #3 elif 조건 : 실행할 문장 #4 : : else: 실행할 문장 #5 |
어떠한 조건에 해당하지 않는 경우에 대해서 처리를 할 수 있도록 'else'문이라는 것이 존재한다.
[형식]
조건식이 참일 경우에는 if문 아래의 문장이 실행되고, 그 외의 경우는 else문 아래의 문장이 실행된다. 참고로 else문은 if문에 종속적이며, else문 홀로 쓰일 수 없다.
>>> price = 123
>>> if price >= 100:
print("price 값이 크거나 같다.")
else :
print("price 값이 작다.")
price 값이 크거나 같다.
>>>
if ~ else 문에서 한 가지 주의해야 할 점은 바로 들여쓰기이다.
위의 예시 코드에서 if 키워드 앞에는 공백이 없지만 else 키워드를 들여쓰기 하면 else 앞에는 4칸의 공백이 존재하기 때문에 if와 else의 들여쓰기가 서로 다르면 파이썬에서는 문법 에러가 발생한다.
즉, 다음과 같은 경우 에러가 발생한다.
>>> price = 123
>>> if price >= 100:
print("price 값이 크거나 같다.")
else :
print("price 값이 작다.")
파이썬 IDLE를 처음 사용할 때는 오히려 다음과 같은 코드가 if와 else의 들여쓰기가 잘못된 것처럼 보인다.
그러나 파이썬 IDLE의 프롬프트(>>>)를 지워보면 실제로는 if와 else가 같은 위치에서 시작됨을 확인할 수 있다.
if문과 else문 사이에 elif문이라는 것을 사용하여 다양한 조건 판단을 할 수 있게 만들 수 있다.
if ~ else 문을 이용하면 if 문 뒤에 존재하는 조건식이 참이냐 거짓이냐에 따라 다음 그림과 같이 두 개의 코드 블록 중 하나를 실행할 수 있었다.
[예제] 숫자를 입력받아 홀수/짝수 구분하는 프로그램
# coding: euc-kr
data = int(input("숫자를 입력하시오: "))
if data % 2 == 0:
print("입력된 값은 짝수입니다.")
else:
print("입력된 값은 홀수입니다.")
그런데 실행해야 할 경우의 수가 두 가지가 아니라 그보다 많은 경우에는 이럴 때 사용할 수 있는 추가 키워드가 바로 elif이다.
elif 키워드는 '그렇지 않고 ~이면' 정도의 뜻을 가진다.
[형식]
위 형식을 보면, if문의 조건식의 결과가 거짓일 때 elif문의 조건식을 검사하며 이 조건식마저도 거짓일 때 아무런 조건에도 해당하지 않으므로 else문의 문장이 실행된다.
먼저 money의 값이 500보다 큰지 검사한다. 변수 money의 값은 500이므로, 500보다 크지 않아 elif문으로 넘어간다. elif문에서는 money의 값이 500과 같은지 검사하는데, money의 값과 500이 서로 같으므로 '가지고 있는 돈이 500원입니다.' 라는 문장을 출력한다. 그리고 마지막의 else문은 하나라도 조건이 해당하는 것이 있으므로 실행되지 않는다.
[예제 1] 키보드로 나이와 키를 입력받아 조건을 처리하여 다음과 같이 출력되는 프로그램
[출력결과]
# coding: euc-kr
age = int(input("나이를 입력하시오"))
height = int(input("키를 입력하시오"))
if age >= 40:
if height >= 170:
print("키가 보통 이상 입니다.")
else:
print("키가 보통입니다.")
else:
if height >= 175:
print("키가 보통 이상 입니다.")
else:
print("키가 보통입니다.")
[예제 2] 키보드로 총점을 입력받아 점수에 따라“수, 우, 미, 양, 가”를 출력하는 프로그램
# coding: euc-kr
score = int(input("총점을 입력해 주세요: "))
if score >= 90:
print("수")
else:
if 80 <= score < 90:
print("우")
else:
if 70 <= score < 80:
print("미")
else:
if 60 <= score < 70:
print("양")
else:
print("가")
[예제 3] 단계가 많아질수록 한 쪽으로 치우친 if ~ else문이 작성되는데, 이러한 경우 if ~ elif 구문이 적합하다.
# coding: euc-kr
score = int(input("총점을 입력해 주세요: "))
if score >= 90:
print("수")
elif 80 <= score < 90:
print("우")
elif 70 <= score < 80:
print("미")
elif 60 <= score < 70:
print("양")
else:
print("가")
4. 반복문(Loop)
반복문이란, 쉽게 생각하면 이름 그대로 반복에 사용되는 것으로 파이썬은 다른 언어와 다르게 반복문은 두 가지로 한정되어 있다.
파이썬에서 지원하는 반복문에는 조건문이 참인가 거짓인가에 따라 반복을 진행하는 while문이라는 것이 존재하고, 리스트나 튜플같은 순서형 자료의 아이템을 하나씩 가져오면서 반복을 수행하는 for문이 존재한다.
1) For
for문은 튜플, 리스트, 사전, 문자열 등과 같은 순서형 자료를 반복하여 처리한다.
즉, for문은 순서형 자료(리스트, 튜플 등)의 요소를 하나하나씩 가져와서 변수에 넣는다.
또한ㄴ, 리스트의 len 함수와 range 함수를 이용하면 for 문에서 사용할 수 있는 일련의 인덱스를 생성할 수 있다.
[형식]
위 예제를 보면, 리스트 lst의 요소를 하나하나씩 가져와 변수 i에 넣어서 i의 값을 출력하고 있음을 확인할 수 있다. 그리고 또한 for문에도 역시 break문과 continue문을 사용할 수 있다.
위 예제의 for문 내부 블록을 보면, i를 2로 나눈 뒤의 나머지가 1인 경우에 시작 지점으로 돌아가고 i가 6과 같으면 반복문을 탈출하게 된다.
1, 3, 5는 첫 번째 조건문에 의해 시작 지점으로 돌아가 출력이 되지 않은 것이며, 6부터는 두 번째 조건문을 만나 반복문을 탈출하여 이후의 문장이 수행되지 않는 것이다.
[예제] 1~10까지의 합을 구하는 프로그램
# coding: euc-kr
total = 0
for item in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
total = total + item
print("1부터 10까지 합은", total, "입니다.")
예를 들어, 1부터 10까지 숫자를 출력한다고 가정해 보자.
파이썬에 반복문이 없다면 다음 코드와 같이 한번에 하나씩 출력해야 할 것이다. 그러나 10까지가 아니라 100까지 출력해야 할 경우 이를 코드를 작성하려면 시간이 오래 걸리고 지루할 것이다. 이럴 때 사용하는 것이 바로 반복문이다.
for 문을 사용하면 1~10까지를 출력하는 기능을 다음과 같이 구현할 수 있다.
위 코드에서는 화면에 문자열을 출력하는 함수인 print를 단 한 번만 사용했지만 화면에는 0부터 10까지의 값이 출력된 것을 확인할 수 있다. 이처럼 for 문을 사용하면 중복적인 부분의 코드를 줄일 수 있어 프로그램을 더욱 빨리 개발할 수 있고 코드의 가독성도 향상된다.
또한, 순서형 자료는 리스트나 사전과 같은 타입을 말하며, 다른 객체들을 가지고 있는 컨테이너를 의미한다.
즉, 순서형 자료를 이터레이터라고도 하는데, 이는 컨테이너에서 아이템을 하나하나 꺼낼 수 있는 타입을 의미하고, 리스트는 아이템이 숝서대로 들어가 있는 구조이므로 아이템을 순서대로 반환하고, Set는 순서 없이 저장되는 구조이므로 고정된 순서가 없는 아이템들을 순차적으로 반환한다.
파이썬의 튜플은 리스트와 유사하게 데이터를 순서대로 저장할 수 있는 자료구조이지만, 리스트와 달리 튜플은 한번 만들어지면 수정할 수 없습니다.
또한, 튜플은 수정할 수 없기 때문에 리스트보다 빠르다.
변경할 필요가 없는 경우에는 튜플로 관리하고 파이썬의 for 문을 사용하는 것이 좋고, 변경할 필요가 있는 경우에는 데이터를 리스트로 관리하는 것이 좋다.
① 리스트 예
위 예제를 보면 리스트 lst의 요소를 하나하나씩 가져와 변수 i에 넣어서 i의 값을 출력하고 있다.
예제) 다음과 같은 출력을 하는 프로그램을 구현하여 보세요.
[출력 결과]
문자열 “Hello!"를 순차적으로 출력한다.
H
e
l
l
o
!
리스트 [“Hello Python"]을 순차적으로 출력한다.
Hello Python
듀플 (1, 2, 3)을 순차적으로 출력한다.
1
2
3
message = "Hello!"
messages = ["Hello Python"]
numbers = (1, 2, 3)
for item in message:
print("문자열 “Hello!"를 순차적으로 출력한다.")
print(item)
print()
for item in messages:
print("리스트 [“Hello Python"]을 순차적으로 출력한다.")
print(item)
print()
for item in numbers:
print("듀플 (1, 2, 3)을 순차적으로 출력한다.")
print(item)
② 사전과 집합 예
사용자가 지정한 순서가 유지되지 않는 비순차 데이터 타입으로 파이썬 인터프리터가 지정한 순서대로 데이터 요소를 하나씩 접근하면서 반복문이 수행된다.
polygon = {"triangle":2, "rectangle":3, "line":1}
color = {"red", "green", "blue"}
for item in polygon:
print(item)
print()
for item in color:
print(item)
[결과]
결과를 확인해 보면,
사전 {"triangle":2, "rectangle":3, "line":1}과 집합 {"red", "green", "blue"}은 입력된 순서가 유지되지 않는 것을 확인할 수 있으며, 수행시마다 접근하여 처리되는 결과가 다르다.
그러나, 각 요소를 하나씩 모두 접근한다는 것은 리스트와 동일하며, 사전의 경우 키를 중심으로 하나씩 접근한다.
즉, 딕셔너리는 키-값 쌍을 저장하는 구조라는 것을 명심해야 하며, 딕셔너리에 대해 for 문을 사용하려면 조금 특별한 방법이 필요하다.
stocks = {"Naver":10, "Samsung":5, "SK Hynix":30}
for company, stock_num in stocks.items():
print("%s: Buy %s" % (company, stock_num))
위의 예제에서 확인할 수 있듯이
stocks이라는 딕셔너리에 있는 키-값 쌍에 대해 동작을 반복적으로 수행하려면 for 문을 사용하면 되는데, 딕셔너리의 한 원소에는 키와 값이 있기 때문에 for 문 다음에 있는 변수가 한 개가 아니라 두 개를 적어야 한다. 그리고 딕셔너리 이름을 적은 다음 .items( )를 붙여야 한다.
즉, 위 코드를 보면 company와 stock_num이라는 두 변수가 바인딩하는 값을 출력하기 위해 두 개의 %s를 사용했고 % 기호 다음에 실제 변수명을 지정할 때는 (company, stock_num)과 같이 튜플로 표현한 것을 확인할 수 있다.
딕셔너리의 키-값 쌍만을 구하기 위해 keys()와 values()이라는 메서드를 사용했다. 딕셔너리의 keys() 메서드를 이용하면 다음과 같이 코드를 작성할 수도 있다.
stocks = {"Naver":10, "Samsung":5, "SK Hynix":30}
for company in stocks.keys():
print("%s: Buy %s" % (company, stocks[company]))
앞에서 설명한 것처럼 stock.keys()의 반환값은 dict_keys(['SK Hynix', 'Naver',
'Samsung'])인데, 이것은 리스트는 아니지만 이를 명시적으로 리스트로 변환할 필요는 없다. 파이썬의 for 문은 dict_keys 타입에 대해서도 제대로 동작하기 때문이다.
③ Range
range 함수는 범위를 생성하는 함수이다.
앞서 for라는 파이썬 키워드를 사용해 단 두 줄의 코드로 화면에 0부터 10까지를 출력해 봤다. 그러나 한 가지 불편한 점은 출력하고자 하는 숫자를 리스트를 통해 명시적으로 저장하고 있어야 한다는 점이다. 물론 앞의 예시처럼 반복하는 데이터가 많지 않은 경우에는 리스트를 사용해 명시적으로 데이터를 나열할 수 있다.
그렇지만 데이터가 많을 경우에 사용하는 것이 바로 range입니다.
파이썬에서 range를 이용하면 간단히 정수 범위를 표현할 수 있다.
예를 들어, range(1, 10)은 1부터 9까지의 숫자 범위를 나타낸다.
>>>range(1, 10)
range(1, 10)
[예]
>>> range(0, 10, 1)
range(0, 10, 1)
>>> list(range(0, 10, 1))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(0, 10, 2))
[0, 2, 4, 6, 8]
파이썬 range에서 중요한 점은 시작 숫자와 끝 숫자를 지정했을 때 끝 숫자는 범위에 포함되지 않는다는 점이다.
이를 확인하기 위해 range(1, 10)을 list()를 통해 리스트 객체로 변환해보면 리스트에 1부터 9까지만 저장돼 있음을 확인할 수 있다.
range를 이용하면 큰 수의 범위에 대해서도 for 문을 쉽게 작성할 수 있다.
먼저 0부터 10까지의 숫자를 출력하는 코드를 for와 range를 사용해 다시 작성해 보자.
다음 코드를 보면 in 다음에 리스트를 사용하는 경우보다 코드가 매우 간단하다는 것을 확인할 수 있다. 0부터 10까지 출력하기 위해 range(0, 10)이 아니라 range(0, 11)이라는 표현이 사용된 것에 유념하자.
또한, 위의 코드를 다음 코드와 같이 작성할 수도 있다.
range(0, 11)을 list라는 키워드를 이용해 리스트 객체로 변환한 후 해당 리스트 객체에 대해 for 문을 수행했다. range(0, 11)을 사용한 것과 list(range(0, 11))을 사용한 것의 실행 결과는 동일하다. 다만 list(range(0, 11))과 같이 명시적으로 리스트 객체로 변환하기보다는 range(0, 11)을 그대로 사용하는 편이 메모리 사용 관점에서 더 효율적이다.
즉, range 객체를 그대로 사용하면 for 문에서 필요할 때마다 값을 i라는 변수가 바인딩해서 사용하게 되지만 리스트 객체로 변환하면 모든 범위의 값을 한 번에 리스트로 만들어서 저장하기 때문에 더 큰 메모리가 필요해진다. 메모리 절약뿐만 아니라 코드 가독성 측면에서도 range 객체를 그대로 사용하는 편이 더 간결해 보인다.
[range 활용 예]
range의 시작 값을 생략할 수 있다.
위 예제에서는 range(10)이 0에서부터 9까지의 범위를 지니는 range 객체를 만들어내며, 이 객체를 가지고 순차적으로 접근하여 값이 i에 담긴 뒤, 저장된 i의 값을 print문으로 출력하는 것이다. 이를 리스트에서 응용하게 되면 다음 예제와 같이 사용할 수 있다.
len 함수를 통해 리스트 lst의 요소 수를 구하고 이 요소 수를 통해 range 함수를 호출하여 요소 수 만큼 반복하게 된다. for문의 내부 블록을 보면 i를 2로 나눈 나머지가 0인 경우, 즉 짝수인 경우에는 i번째 요소의 값에 2를 곱한 값을 저장하고, 홀수인 경우에는 i번째 요소의 값에 -2를 곱한 값을 저장한다.
결과를 보면 "2 -4 6 -8 10"과 같은 결과를 확인할 수 있으며, 위의 예제에서는 0~4의 범위를 지닌 range 객체를 만들어 낸 것이라고 보면 된다.
[예제 1] range를 활용하여 1~10까지의 합을 구하는 프로그램
# coding: euc-kr
total = 0
for item in range(1, 11):
total = total + item
print("1부터 10까지 합은", total, "입니다.")
[예제 2]
# coding: euc-kr
total = 0
for item in range(1, 101):
total = total + item
else:
print("덧셈 작업이 끝났습니다.")
print("1부터 100까지 합은", total, "입니다.")
[ for 루프 예]
#coding: euc-kr
y = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
z = ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']
# 변수 y에 있는 12개월의 이름을 담은 리스트 값들을 출력
print("Output #1:")
for month in y:
print("{!s}".format(month))
# range 함수와 len 함수를 결합하여 인덱스 값을 생성한다.
print("Output #2:(index value: name in list)")
for i in range(len(z)):
print("{0!s}: {1:s}".format(i, z[i]))
#생성된 인덱스들을 이용하여 다음 시퀀스의 동일한 인덱스에 해당하는 값에 접근
print("Output #3:(access elements in y with z index values)")
for j in range(len(z)):
if y[j].startswith('J'): # z로부터 얻은 인덱스 값에 해당하는 리스트 y의 값들
# (y[0]='Jan', y[1]='Feb',....y[11]='Dec')이 대문자 J로
# 시작하는지 확인
print("{!s}".format(y[j]))
# 딕셔너리의 키와 값에 반복해서 접근한다.
print("Output #4:")
for key, value in a_dict.items():
print("{0:s}, {1}".format(key, value))
2) While
반복해야 할 횟수가 특별히 정해지지 않고 어떤 조건을 충족하는 동안만 실행될 때 주로 사용하며, for 문을 사용하나 while 문을 사용하나 결과는 동일하다.
또한, while문은 조건식을 가지며, 조건식이 참이라면 while문 내부에 있는 블록의 문장을 실행하고, 거짓이면 반복을 멈추고 빠져나온다.
[형식]
while 다음에 조건식이 오며, 조건식 뒤에는 콜론(:)이 따라붙는다.
for 문과 같이 0부터 10까지의 숫자를 while 문을 사용해 화면에 출력해 보자.
다음 코드를 보면 먼저 i라는 변수가 초깃값으로 0을 바인딩하고 while 문에는 조건문(i <= 10)이 있는데, 현재 i가 바인딩하는 값이 10보다 작거나 같으므로 해당 조건을 만족한다.
조건문이 참이므로 while 문에 속하는 문장을 순서대로 실행한다. 즉, print(i)라는 문장이 먼저 실행되고 현재 i라는 변수가 바인딩하고 있는 값인 0이 화면에 출력된다. 그리고 'i = i+1'이라는 문장이 수행되어 i가 바인딩하는 값이 0에서 1로 바뀐다.
while 문에 속하는 모든 문장이 수행된 경우 다시 while 문의 조건문으로 이동한 후 조건식을 다시 판단한다.
i라는 변수가 1을 바인딩하고 있지만(앞에서 1 증가했으므로) 여전히 10보다는 작거나 같은 값이므로 여전히 조건식은 참이 된다. 따라서 while 문에 속하는 문장을 차례로 수행한다. 이러한 방식으로 i라는 변수가 바인딩하는 값이 10일 때까지 while 문 내부의 문장을 순서대로 수행하고 i가 11이 될 때 더는 조건식을 만족하지 않아 while 문을 빠져나오게 된다.
위 코드에서 i라는 변수는 초깃값으로 0을 바인딩하고 있었다. 그러나 while 문에서 조건문을 만족할 때마다 값이 1씩 증가했는데, 정말로 i 값이 증가했는지 확인해 본다.
다음 코드와 같이 파이썬 IDLE에서 i 값을 확인해보면 i 값이 11로 증가한 것을 확인할 수 있다. 앞서 설명한 것처럼 i 값이 11이 되면 더는 while 문의 조건식(i <= 10)을 만족하지 않기 때문에 while 문을 빠져나오게 되는 것이다.
>>> i
11
다음 예제를 보자.
위의 예제를 보면 조건식에 'i <= 10'이 주어졌다. 이는 변수 i의 값이 10보다 작거나 같은 경우에 참이 성립되며, 10보다 큰 경우는 거짓에 해당한다. 그리고 'i += 1'과 같은 코드는 i의 값을 1만큼 증가시키는 'i = i + 1'를 축약한 코드로, 반복문을 빠져나오도록 되어 있다. 만약에 while문의 조건식이 처음부터 거짓이면 내부 블록에 있는 문장이 단 한번이라도 실행되지 않는데, 이유는, while문의 실행 순서는 '조건식을 검사 → 내부 블록에 있는 문장을 실행 → 조건식을 검사 → ...'이러한 순서를 따르기 때문이다.
다음 예제를 이용하여 While을 이해하도록 해보자.
먼저 wikibooks라는 변수에 10,000원을 바인딩했고 날짜를 저장하는 변수인 day에 초기값으로 1을 바인딩했다.
현재 day는 1을 바인딩하고 있으므로 'day < 6'의 조건을 만족합니다. 조건문을 만족하기 때문에 while 문 안쪽에 들여쓰기된 코드가 순서대로 수행된다. 따라서 먼저 wikibooks가 바인딩하는 값에 0.3을 곱한 값이 계산되고 이 값이 현재 wikibooks가 바인딩하고 있는 값에 더해진다. 이렇게 최종 계산된 값을 다시 wikibooks라는 변수가 바인딩하게 된다. 따라서 wikibooks는 13,000원을 바인딩하게 된다. 그런 후 day라는 변수의 값이 1 증가해서 2가 된다.
이러한 동작은 day 값이 5일 때까지 반복되므로 총 5번의 wikibooks라는 변수가 바인딩하게 됩니다.
while 문의 동작 원리는 다음과 같다.
① while 문의 조건 확인
② 조건을 만족하면 while 문 내부의 코드를 차례로 수행하고, 조건을 만족하지 않으면
while 문의 다음 문장을 수행
③ ②의 과정에서 while 문 내부의 코드를 차례로 수행한 경우 다시 while 문의 조건 확인
으로 이동
[예제] while을 활용하여 1~100까지의 합을 구하는 프로그램
# coding: euc-kr
count = 1
total = 0
while count <= 100:
total = total + count
count = count + 1
print("1부터 100까지의 합은:", total)
[while과 if]
파이썬의 반복문 중 하나인 while 문과 분기문인 if 문을 함께 사용하는 예이다.
이러한 코드는 반복적인 작업을 수행하다가 특정 조건일 때는 다르게 처리하고자 할 때 많이 사용한다.
예를 들어, 앞에서는 while 문을 이용해 0부터 10까지의 숫자를 화면에 출력해봤는데, while문과 if문을 함께 사용하면 0부터 10까지의 숫자 중 홀수만 출력하는 프로그램을 구현할 수 있다.
while 문에서 조건을 만족하는 경우 while 문 내에서 들여쓰기된 문장을 순서대로 수행하게 되는데, 이때 홀수인 경우에만 화면에 숫자를 출력하면 된다.
다음 코드는 while문과 if문을 사용하여 0부터 10까지의 숫자 중에서 홀수만 화면에 출력하는 프로그램이다.
[break와 continue]
① break
위 코드는 “Find stocks"라는 문장을 무한 출력하게 되며, 강제 중단을 위해 CTRL+C키를 사용해서 중단해야 한다.
파이썬의 반복문(while 문 또는 for 문)에서 빠져나오려면 break이라는 키워드를 사용하면 된다. 위 코드에서 무한 루프는 원래 무한히 반복해야 하는데, 여기에 break이라는 키워드를 넣어주면 break를 만나는 순간 해당 위치에서 반복문을 빠져나오게 된다.
다음 코드를 실행해 보면 먼저 while 문의 조건식을 판단하게 되고 조건식에 1이라는 숫자만 있으므로 참으로 판단된다. 참고로 거짓이 되려면 0이라는 값이 있어야 하고 0이 아닌 다른 숫자가 있으면 모두 참으로 판단한다.
while 문의 조건이 참이므로 while 문 내의 코드가 실행되고 따라서 먼저 print("Find stocks")라는 문장이 실행되고, 그 결과 화면에 'Find stocks'라는 문자열이 출력된다. 그다음 break 문이 실행되는데 break라는 키워드는 루프를 빠져나가게 하므로 더는 코드가 실행되지 않고 프로그램은 종료된다.
* 무한 반복은 반복문을 빠져 나오지 못하고 특정 문장들을 계속 반복하는 경우이다.
# coding: euc-kr
choice = None
while True:
print("1. 원 그리기")
print("2. 사각형 그리기")
print("3. 선 그리기")
print("4. 종료")
choice = input("메뉴를 선택하시오: ")
if choice == "1":
print("원 그리기를 선택했습니다.")
elif choice == "2":
print("사각형 그리기를 선택했습니다.")
elif choice == "3":
print("선 그리기를 선택했습니다.")
elif choice == "4":
print("종료합니다.")
break
else:
print("잘못된 선택을 했습니다.")
while 문 내에서 if 문을 이용해 현재 숫자가 10이면 break를 통해 while 문 바깥으로 나가도록 작성하여 보자.
[예제 1]
[예제 2] 키보드로 특정 문자를 입력받아 프로그램을 종료하는 프로그램
# coding: euc-kr
break_letter = input("중단할 문자를 입력하시오: ")
for letter in "python":
if letter == break_letter:
break
print(letter)
else:
print("모든 문자 출력 완료!")
② continue
while 문이나 for 문을 사용하는 반복문에서 break를 사용하면 반복문 전체를 빠져나오게 된다. 그런데 반복문 전체를 빠져나오는 것이 아니라 해당 조건만 건너뛰고 싶은 경우 이럴 때 사용할 수 있는 키워드가 바로 continue이다.
위 코드를 참조하면 while 문 내에서 먼저 num 값을 증가하게 했고 증가한 num 값이 5와 같으면 continue가 실행되도록 구현하였다. 파이썬 프로그램이 실행되다가 continue를 만나면 그 아래의 코드를 수행하지 않고 while 문의 조건을 판단하는 곳으로 점프하게 된다. 따라서 다음 코드를 실행하면 num 값이 5일 때는 화면에 5가 출력되지 않은 채로 다시 while 문의 조건식으로 이동하게 되고 그다음 'num += 1'에 의해 num 값이 5에서 6으로 증가하게 된다.
[예제 1] continue를 활용한 키보드로 건너뛸 문자를 입력하여 출력하는 프로그램
# coding: euc-kr
continue_letter = input("건너뛸 문자를 입력하시오: ")
for letter in "python":
if letter == continue_letter:
continue
print(letter)
[예제]
위 예제는 continue문을 만나면, continue문 아래의 문장은 실행하지 않고 반복문의 시작 지점으로 되돌아간다. 즉, 반복문의 조건을 검사하는 부분으로 다시 되돌아간다.
직접 코드를 따라가보면, i의 값이 처음에 0이고 반복문 내에서 i가 1이 증가하고 i를 2로 나누어 나머지가 1인지 검사를 하는 코드가 존재한다. 만약 i를 2로 나눈 뒤의 나머지가 1이면 이것은 홀수라는 의미가 되며, 홀수는 continue문을 만나게 된다.
출력된 결과를 보면, 홀수가 제외되어서 출력되었음을 확인할 수 있다. 홀수는 continue문을 만나 시작 지점으로 되돌아가고 i의 값이 증가하기 때문에 그렇다. 반대로 짝수라면 continue문을 만나지 않고, 그 아래의 문장을 계속 수행해나간다.
* 참고적으로 pass문은 문법적으로 문장이 필요하지만 어떠한 동작도 원치 않을 경우에 사용한다.
[예제 1]
coding: euc-kr
input_letter = input("중단할 문자를 입력하시오: ")
for letter in "python":
if letter == input_letter:
pass
print(letter)
③ 반복문의 중첩
반복문의 중첩이란, 반복문 내에 반복문이 들어가는 것으로써 for문 내에 while문이 들어갈수도 있으며, while문 내에 while문이 들어갈 수 있는 등 여러 개의 반복문이 중첩되어 사용될 수 있다.
예를 들면, 반복문 중첩을 통해 구구단을 모두 출력할 수 있다.
위 예제처럼 while문을 사용할 수 있으나, 아래처럼 for문을 사용할 수도 있다.
[종합 예제 1] 요일 구하기 예제를 통해본 흐름 제어
요일 구하는 프로그램에서는 년, 월, 일을 입력 받아서 요일을 구한다.
요일을 구하는 공식은 다음과 같다.
-서기 1년 1월 1일은 월요일이다.
-윤년을 구하는 공식은 다음과 같다.
-4로 나누어지는 해는 유년이다.
-100으로 나누어지는 해는 유년이 아니다.
-400으로 나누어지는 해는 유년이다.
따라서, 요일은 서기 1년 1월 1일부터 입력된 날까지의 날수를 모두 더한 값을 7로 나누어 나머지가 1이면 월요일, 2이면 화요일, 3이면 수요일....0이면 일요일과 같이 정한다.
[출력 결과]
# coding: euc-kr
# 년월일을 입력 받는다.
year = int(input("년도를 입력하시오: "))
month = int(input("월을 입력하시오: "))
day = int(input("일을 입력하시오: "))
total_days = 0
# 달별 날수를 리스트로 저장
year_month_days = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
# 서기 1년부터 year-1 까지의 각 년도 별 날수를 합한다.
for item in range(1, year):
if item % 400 == 0: # 400으로 나뉘는 해 (윤년)
total_days = total_days + 366
elif item % 100 == 0: # 100으로 나뉘는 해 (윤년 아님)
total_days = total_days + 365
elif item % 4 == 0: # 4로 나뉘는 해 (윤년)
total_days = total_days + 366
else:
total_days = total_days + 365
# 1월 달부터 month-1 까지의 각 달의 날수를 합한다.
for item in range(1, month):
total_days = total_days + year_month_days[item]
# 입력된 달이 3이상이고 해당년도가 윤년일 경우 1을 추가
if month >= 3:
if year % 400 == 0:
total_days = total_days + 1
elif year % 100 == 0:
total_days = total_days + 0
elif year % 4 == 0:
total_days = total_days + 1
else:
total_days = total_days + 0
total_days += day
# 총 날수를 7로 나눈 나머지를 구한다.
remainder = total_days % 7
if remainder == 0:
print("일요일 입니다.")
elif remainder == 1:
print("월요일 입니다.")
elif remainder == 2:
print("화요일 입니다.")
elif remainder == 3:
print("수요일 입니다.")
elif remainder == 4:
print("목요일 입니다.")
elif remainder == 5:
print("금요일 입니다.")
elif remainder == 6:
print("토요일 입니다.")
[종합 예제 2] 성적 처리 시스템 구현을 통한 흐름제어
반복 처리 구문을 이용하여 학생들의 데이터가 늘어나도 프로그램 상에서 수정할 부분이 없이 처리 가능한 프로그램
[출력 결과]
# coding: euc-kr
students = [{"num": "1", "name":"김민규", "kor": 90, "eng": 80, "math": 85, "total":
0.0, "order": 0},
{"num": "2", "name":"김용학", "kor": 90, "eng": 85, "math": 90, "total":
0.0, "order": 0},
{"num": "3", "name":"박영철", "kor": 80, "eng": 80, "math": 80, "total":
0.0, "order": 0}]
class_total = 0
class_avg = 0.0
kor_total = 0
kor_avg = 0.0
eng_total = 0
eng_avg = 0.0
math_total = 0
math_avg = 0.0
for student in students:
student["total"] = student["kor"] + student["eng"] + student["math"]
student["avg"] = student["total"] / 3
class_total = class_total + student["total"]
kor_total = kor_total + student["kor"]
eng_total = eng_total + student["eng"]
math_total = math_total + student["math"]
class_avg = class_total / len(students)
kor_avg = kor_total / len(students)
eng_avg = eng_total / len(students)
math_avg = math_total / len(students)
for student in students:
print("번호: %s, 이름: %s, 국어: %d, 영어: %d, 수학: %d, 총점: %d, 평균:%.2f"
% (student["num"], student["name"], student["kor"], student["eng"], student["math"],
student["total"], student["avg"]))
print()
print("반 평균: %.2f" % class_avg)
print("국어 평균: %.2f" % kor_avg)
print("영어 평균: %.2f" % eng_avg)
print("수학 평균: %.2f" % math_avg)
'Language > Python' 카테고리의 다른 글
Python에서 Excel 사용 (0) | 2020.02.26 |
---|---|
파이썬 - 함수와 모듈 (0) | 2020.02.26 |
python 소개 (0) | 2020.02.26 |
os.walk : 하위 디렉터리 검색을 쉽게 해주는 (0) | 2020.02.26 |
python No module named 'cv2' 에러처리 (0) | 2020.02.26 |