제어문

maro·2024년 3월 14일

제어문(Control flow statement)

기본적으로 프로그램은 순차구조를 가진다. 즉 작성한 순서대로 실행이 된다.
이런 실행흐름을 다른 순서로 제어하기 위한 구문을 만드는 문법이 제어문이다.
제어문은 조건문 과 반복문 두가지 문법이 있다.

조건문

  • if 문

반복문

  • while 문
  • for in 문

조건문/분기문 (conditional statement)

  • 프로그램이 명령문들을 실행하는 도중 특정 순서에서 조건에 따라 흐름의 나눠져야 하는 경우 사용한다
  • 파이썬은 조건문으로 if문이 있다.

구문

조건이 True일 경우만 특정 구문들을 실행 하는 조건문.

파이썬의 코드블록(code block)

코드블록이란 여러 명령문들을 묶어놓은 것을 말한다. 코드블록으로 묶이면 실행시 같이 다 실행되고 실행이 안되면 같이 다 실행이 안된다.
파이썬에서는 코드블록을 작성할 때 들여쓰기를 이용해 묶어준다.
같은 칸만큼 들여쓰기를 한 명령문들이 같은 블록으로 묶인다. 들여쓰기는 관례적으로 공백 4칸을 사용한다.

pass 키워드(예약어)

빈 구현부를 만들때 사용
제어문, 함수의 body 코드블럭은 비울 수 없다. 반드시 명령문을 한개 이상 작성해야한다.
작성할 내용이 없을 경우 사용하는 키워드로 pass를 사용한다.

city = input("도시이름 : ")
if city == "서울" :
    print("특별시")
elif city in ["인천", "부산", "광주", "울산", "대구",] :
    print("광역시")
elif city in ["제주", "강원"] :
    print("특별자치도")
else :
    print("일반시")
print("종료")

도시이름 : 안양
일반시
종료

반복문 (Loop statement)

특정 구문들을 반복해서 실행할 때 사용한다. 동일한 코드를 여러번 반복하거나 값이 일정하게 변하는 코드를 반복할 경우 사용한다.
단순 반복을 처리하는 while문과 iterable객체가 제공하는 값들을 반복 조회하는 for in문 두가지 문법이 있다.

while문

조건이 True인 동안 구문을 반복해서 실행한다.

limit = int(input("반복횟수 : "))
count = 0 # 몇번째 반복인지 저장할 변수
while limit > count :
    count += 1
    print(f"{count}번째 실행")
print("종료")

반복횟수 : 5
1번째 실행
2번째 실행
3번째 실행
4번째 실행
5번째 실행
종료

for in 문

Iterable 객체를 순환조회하는 구문

  • for in문은 Iterable 타입의 객체가 가지고 있는 값들을 하나씩 처리하는 구문을 작성할 때 사용한다.
  • Iterable
    - 반복가능한 객체. 반복문(for in)을 이용해 일련의 값들을 반복적으로 각각 제공하는 객체를 말한다.
    - 대표적으로 List, Tuple, Dictionary, Set, 문자열 등이 있다.
#l의 모든 값들에 5를 더한 것을 저장
result = []
for v in l :
    r = v + 5
    result.append(r)
result

[15, 10, 7, 12, 25]

continue와 break를 이용한 반복문 제어

continue

  • 실행 블록에서 continue가 실행되면 현재 반복을 중단하고 다음 반복을 진행한다.
  • 특정 조건에서 처리를 멈추고 다음 처리를 반복할 때 사용한다.

break

  • 반복문 실행을 중단한다.

continue와 break는 특정 조건에서 실행되야 하는 경우가 대부분이므로 if문 안에 작성한다.

#10 ~ 30 사이의 랜덤정수를 추출 -> 20이 나올 때까지
nums = []
while True :
    num = random.randint(10, 30)
    nums.append(num)
    if num == 20 :
        break
print(nums)
print("종료")

[17, 23, 10, 13, 11, 16, 18, 13, 12, 28, 22, 20]
종료

for in 문 연관 내장 함수

range()

일정한 간격의 연속된 정수를 제공하는 반복가능 객체 생성한다.
구문

  • range([시작값], 멈춤값, [증감값])
    - 시작값, 멈춤값, 증감값 모두 정수만 가능하다.
    - 시작값 > 멈춤값 이고 증감값이 음수이면 내림차순으로 값을 제공한다.
    1. 전달값이 1개: 멈춤값.
    : 0 ~ (멈춤값-1)까지 1씩 증가하는 정수를 제공
    2. 전달값이 2개: 시작값, 멈춤값.
    : 시작값 ~ (멈춤값-1) 까지 1씩 증가하는 정수 제공
    3. 전달값이 3개: 시작값, 멈춤값, 증감값(간격).
    : 시작값 ~ (멈춤값-1)까지 증감값만큼 증가하는 정수를 제공.
for i in range(1, 100, 10) :
    print(i, end = "\t") # enter 대신에 다른 출력을 원하면 ,end="" 을 추가하면 됨.

1 11 21 31 41 51 61 71 81 91

enumerate()

구문

  • enumerate(Iterable, [, start=정수])
    - 현재 몇번째 값을 제공하는 지(현재 몇번째 반복인지)를 나타내는 index와 제공하는 원소를 tuple로 묶어서 반환
    - Iterable
    : 값을 제공할 Iterable객체
    - start: 정수
    : index 시작 값. 생략하면 0부터 시작한다.
l = [1, 10, 20, 5, 7]
#첫번째 값은 사용안함.
for index, value in enumerate(l) : 
    if index == 0 :
        continue
    print(index, value)

1 10
2 20
3 5
4 7

zip()

  • 여러 개의 Iterable 객체를 받아 반복시 같은 index의 값끼리 튜플로 묶어 반환한다.

구문

  • zip(Iterable1, Iterable2, Iterable3 [, .......])
    - Iterable 2개이상.전달한다.

각 Iterable이 제공하는 원소의 개수가가 다를 경우 가장 적은 것의 개수에 맞춰 반복한다.

#같은 index의 값이 모으면 한 사람의 정보
names = ["홍길동", "이순신", "유관순", "강감찬"]
ages = [20, 25, 30, 25]
# addresses = ["서울", "인천", "부산", "광주"]
addresses = ["서울", "인천", "부산", "광주", "안양", "제주도"] #개수가 젤 작은 것에 맞춤.
for value in zip(names, ages, addresses) :
    print(value)

('홍길동', 20, '서울')
('이순신', 25, '인천')
('유관순', 30, '부산')
('강감찬', 25, '광주')

for name, age, address in zip(names, ages, addresses) : # 튜플 대입
    print(f"이름:{name}, 나이:{name}, 주소:{address}")

이름:홍길동, 나이:홍길동, 주소:서울
이름:이순신, 나이:이순신, 주소:인천
이름:유관순, 나이:유관순, 주소:부산
이름:강감찬, 나이:강감찬, 주소:광주

l = list(range(1, 10))
l

[1, 2, 3, 4, 5, 6, 7, 8, 9]

l = tuple(range(1, 10))
l

(1, 2, 3, 4, 5, 6, 7, 8, 9)

컴프리헨션(Comprehension)

기존 Iterable의 원소들을 이용해서 새로운 자료구조(List, Dictionary, Set)를 생성하는 구문.

  • 기존 Iterable의 원소들을 처리한 결과나 특정 조건이 True인 값들을 새로운 자료구조에 넣을때 사용.
  • 결과를 넣을 새로운 자료구조 타입에 따라 다음 세가지가 있다.
    - 리스트 컴프리헨션
    - 딕셔너리 컴프리헨션
    - 셋 컴프리헨션

튜플을 tuple() 함수를 이용해서 구현가능.
딕셔너리 컴프리헨션과 셋 컴프리헨션은 파이썬 3 에 새로 추가되었다.

l = [10, 5, 20, -5]
#l의 모든 원소들의 2배한 값을 result 리스트에 담기.
result = []
for v in l :
    result.append(v*2)
result

[20, 10, 40, -10]

[v*2 for v in l] # 리스트 컴프리헨션

[20, 10, 40, -10]

{v*2 for v in l} # 셋 컴프리헨션

{-10, 10, 20, 40}

{ i : v for i, v in enumerate(l)} # 딕셔너리 컴프리헨션

{0: 10, 1: 5, 2: 20, 3: -5}

tuple(v*2 for v in l)

(20, 10, 40, -10)

l2 = list(range(1, 100))
result = []
#l2에서 10의 배수만 골라서 result에 담기. (특정 조건의 값들만 찾기)
for v in l2 :
    if v % 10 == 0 :
        result.append(v)
result

[10, 20, 30, 40, 50, 60, 70, 80, 90]

[v for v in l2 if v % 10 == 0]

[10, 20, 30, 40, 50, 60, 70, 80, 90]

l3 = [
    [1, 2, 3],
    [4, 5, 6]
]
result = []
#l3의 모든 원소들을 두배한 결과를 result 리스트에 담기 (일괄처리)
for values in l3 :
    for v in values : # 중첩된 횟수만큼 for문 써야됨.
        result.append(v*2)
result

[2, 4, 6, 8, 10, 12]

[v * 2 for values in l3 for v in values]

[2, 4, 6, 8, 10, 12]

l3 = [
    [1, 2, 3],
    [4, 5, 6]
]
result = []
#l3의 모든 (짝수) 원소들을 두배한 결과를 result 리스트에 담기 (일괄처리)
for values in l3 :
    for v in values : # 중첩된 횟수만큼 for문 써야됨.
        if v % 2 == 0 :
            result.append(v*2)
result

[4, 8, 12]

[v * 2 for values in l3 for v in values if v % 2 == 0]

[4, 8, 12]

실습

#(1) 사용자로 부터 ID를 입력 받은 뒤 입력받은 ID가 5글자 이상이면 "사용할 수 있습니다."를 5글자 미만이면 "사용할 수 없는 ID입니다."를 출력하세요.
id = input("ID : ")
l = len(id)
if l >= 5 :
    print("사용할 수 있습니다.")
else :
    print("사용할 수 없는 ID입니다.")

ID : jupyter
사용할 수 있습니다.

#(2) 사용자로부터 우리나라 도시명을 입력 받은 뒤 입력받은 도시명이 서울이면 "특별시"를 인천,부산,광주,대구,대전,울산 이면 "광역시"를 나머지는 "특별시나 광역시가 아닙니다."를 출력하세요.
city = input("도시이름 : ")
print("입력받은 도시명 : ", city)
if city == "서울" :
    print("특별시")
elif city in ["인천", "부산", "광주", "대구", "대전", "울산"] :
    print("광역시")
else :
    print("특별시나 광역시가 아닙니다.")   

도시이름 : 서울
입력받은 도시명 : 서울
특별시

#(3-4)
#(3) 아래 리스트의 평균을 구하시오.
jumsu = [100, 90, 100, 80, 70, 100, 80, 90, 95, 85]
sum = 0 #합계를 저장할 변수
for v in jumsu :
    sum = sum + v
avg = sum / len(jumsu)
print(f"합계 : {sum}, 평균 : {avg}")

합계 : 890, 평균 : 89.0

#(4) 위 jumsu리스트에서 평균점수이상은 pass, 미만은 fail을 index번호와 함께 출력하시오. (ex: 0-pass, 1-pass, 2-fail)
for i, v in enumerate(jumsu, start = 1) :
    if v > avg :
        print(f"{i}-pass")
    else :
        print(f"{i}=fail")

1-pass
2-pass
3-pass
4=fail
5=fail
6-pass
7=fail
8-pass
9-pass
10=fail

for v in enumerate(jumsu) :
    if v > avg :
        print("pass")
    else :
        print("fail") # enumerate를 사용하면 v는 튜플이므로 값의 비교가 안됨. 따라서 앞에 인덱스 변수를 써야 하고 enumerate 구문은 항상 순서가 인덱스, 튜플이다.

TypeError Traceback (most recent call last)
Cell In[15], line 2
1 for v in enumerate(jumsu) :
----> 2 if v > avg :
3 print("pass")
4 else :

TypeError: '>' not supported between instances of 'tuple' and 'float'

#(5) 아래 리스트 값들 중 최대값을 조회해 출력하시오.
jumsu = [60, 90, 80, 80, 70, 55, 80, 90, 95, 85]
max = jumsu[0]
for v in jumsu :
    if v > max :
        max = v
print(f"최댓값 : {max}")

최댓값 : 95

#(6) 사용자로부터 정수를 입력받아 그 정수 단의 구구단을 출력하시오.
#ex)
#단을 입력하시오 : 2
#2 x 1 = 2
#2 x 2 = 4
#..
#2 x 9 = 18
dan = int(input("단을 입력하시오 : "))
for v in range(1, 10) : 
    print(f"{dan} X {v} = {dan * v}")
    

단을 입력하시오 : 5
5 X 1 = 5
5 X 2 = 10
5 X 3 = 15
5 X 4 = 20
5 X 5 = 25
5 X 6 = 30
5 X 7 = 35
5 X 8 = 40
5 X 9 = 45

#컴프리헨션
#(7) 다음 리스트의 원소들에 10배한 값을 (원래값, 10배값) 의 튜플 묶음으로 가지는 리스트를 만드시오 (리스트 컴프리헨션 이용)
#Ex) [(10,100), (30,300), .., (35, 350)]
lst = [10, 30, 70, 5, 5, 120, 700, 1, 35, 35]
result = [(v, v * 10) for v in lst]
result

[(10, 100),
(30, 300),
(70, 700),
(5, 50),
(5, 50),
(120, 1200),
(700, 7000),
(1, 10),
(35, 350),
(35, 350)]

result2 = []
for v in lst :
   result2.append((v, v*10))
result2

[(10, 100),
(30, 300),
(70, 700),
(5, 50),
(5, 50),
(120, 1200),
(700, 7000),
(1, 10),
(35, 350),
(35, 350)]

#(8) 다음 리스트가 가진 값들 중 3의 배수만 가지는 리스트를 만드시오. (리스트 컴프리헨션 이용)
lst2 = [3, 20, 33, 21, 33, 8, 11, 10, 7, 17, 60, 120, 2]
result = [v for v in lst2 if v % 3 == 0]
result

[3, 33, 21, 33, 60, 120]

#(9) 다음 파일이름들을 담은 리스트에서 확장자가 exe인 파일만 골라서 새로운 리스트에 담으시오.(string의 endswith()함수 이용)
file_names = [
    "test.txt",
    "a.exe",
    "jupyter.bat",
    "function.exe",
    "b.exe",
    "cat.jpg",
    "dog.png",
    "run.exe",
    "i.dll",
]
result = [name for name in file_names if name.endswith('.exe')]
result

['a.exe', 'function.exe', 'b.exe', 'run.exe']

#(10) 다음 중 10글자 이상인 파일명(확장자포함)만 가지는 리스트를 만드시오.
file_names = [
    "mystroy.txt",
    "a.exe",
    "jupyter.bat",
    "function.exe",
    "b.exe",
    "cat.jpg",
    "dog.png",
    "run.exe",
    "i.dll",
]
result = [name for name in file_names if len(name) >= 10]
result

['mystroy.txt', 'jupyter.bat', 'function.exe']

[(n, len(n)) for n in result]

[('mystroy.txt', 11), ('jupyter.bat', 11), ('function.exe', 12)]

profile
공부 & 프로젝트 & 개발 블로그

0개의 댓글