상세 컨텐츠

본문 제목

[ Python 기초 문법 ] - 제어문(3) - for문

Language/Python

by bing_su 2023. 8. 11. 13:42

본문

반응형
SMALL

이번에 다룰 제어문은 반복문 중에서도 for문에 대해 살펴볼 예정이다.

[ for문의 기본 구조 ]

for을 이용한 반복문의 기본 구조를 살펴보면 아래와 같다.

for (variable) in (list or tuple or string):
    Sentence 1
    Sentence 2
    …

 

for문 기본 구조

위의 기본 코드와 구조 그림을 통해 살펴보자. 변수에 리스트나 튜플, 문자열의 첫 번째 요소부터 마지막 요수까지 차례로 변수에 대입이 되며, for 블록의 문장이 수행된다.

 

아래의 예시를 직접 실습하며 for문의 기본 구조를 살펴보자.

1. 기본 for문 사용

test_list = ['one', 'two', 'three']  # 'one', 'two', 'three'를 요소로 가지는 리스트 선언
for i in test_list:  # 변수 i에 one, two, three를 차례로 대입하며 동작함.
    print(i)  # 반복문이 동작하며 i를 출력.

# 출력 화면
one
two
three

2. 다양한 for문의 사용(튜플 사용)

a = [(1, 2), (3, 4), (5, 6)]  # 리스트의 요솟값이 튜플이 되도록 선언
for (first, last) in a:  # 변수 (first, last)에 a의 각 요소를 대입하며 동작.
    print(first + last)  # 반복문이 동작하며 first와 last 변수 값의 합이 출력됨.

# 출력 화면
3  # 1 + 2
7  # 3 + 4
11  # 5 + 6

튜플을 사용한 변수 값 대입 방법은 이전 게시물을 참고하자.

3. for문 응용

# 5명의 시험 점수에 따른 결과를 출력하는 프로그램

marks = [90, 25, 67, 45, 80]  # 시험 점수를 리스트 변수로 선언
number = 0  # 학생들에게 붙일 번호
for mark in marks:  # 변수 mark에 marks의 각 요소를 대입하며 동작함.
    number = number + 1  # 반복문이 동작하며 학생들의 번호가 +1씩 증가
    if mark >= 60:  # mark 변수가 60보다 크거나 같으면 동작.
        print("{0} Student is Pass.".format(number))  # 결과: pass라고 출력.
    else:  # mark 변수가 60보다 작으면 동작.
        print("{0} Student is Fail.".format(number))  # 결과: fail이라 출력.

[ for문과 continue문 ]

while문에서 살펴본 continue문을 for문에서도 사용할 수 있다. 즉, for문 내부의 문장을 수행하다가 continue문을 만나면 이후 문장을 수행하지 않고 for문의 처음으로 돌아가게 된다. (while문에서의 continue문은 이 게시물 설명 참고.)

 

바로 위에서 다뤘던 예제를 응용하여, continue문을 사용하여 pass한 사람만을 출력하는 프로그램을 작성할 수 있다.

marks = [90, 25, 67, 45, 80]
number = 0
for mark in marks:
    number = number + 1
    if mark < 60: continue  # 60점보다 mark 변수 값이 작으면 맨 처음으로 돌아감.
    print("{0} Student is Pass.".format(number))  # 60점보다 큰 mark 변수 값을 가진 학생만 출력됨.
    
# 출력 화면
1 Student is Pass.
3 Student is Pass.
5 Student is Pass.

점수가 60점보다 작으면 'mark < 60' 조건문이 참이 되어 continue문이 수행된다. 즉, 통과 메시지를 출력하는 부분인 print문을 결국 수행하지 않고 for문의 처음으로 돌아가게 된다. 따라서 60점 이상인 학생들만 출력되는 것이다.

[ for문과 자주 사용되는 range 함수 ]

<< range 함수의 기본 사용법  >>

>>> a = range(10)
>>> a
range(0, 10)  # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9를 포함하는 객체

range(10)은 0부터 10 미만의 정수를 포함하는 range 객체를 만든다. (객체에 대한 개념은 추후에 설명할 예정) 앞서 살펴봤던 슬라이싱과 같이 끝 숫자는 포함되지 않는다. (끝 숫자 직전까지만 포함) 이러한 range 함수는 for문에 아래와 같이 이용할 수 있다.

# 1부터 10까지 덧셈한 결과를 출력하는 프로그램

add = 0  # 합을 출력하기 위한 변수 선언
for i in range(1, 11):  # i 변수에 1부터 10까지 차례로 대입하며 동작.
    add = add + i  # add 변수에 i 만큼 계속 더하며 반복문 동작함.
print(add)  # add 변수에 담긴 최종 값이 출력됨.

# 출력 화면
55

앞서 살펴봤던 '60점 이상이면 pass' 문구를 출력하는 프로그램도 range 함수를 이용하여 작성할 수 있다.

marks = [90, 25, 67, 45, 80]
# len(marks) = 5(리스트 요소 개수) -> range(len(marks)) == range(5)
for number in range(len(marks)):  # number 변수에 0부터 4까지 대입하며 반복문 동작.
    # marks[number]: 차례로 90, 25, 67, 45, 80 값을 가짐
    if marks[number] < 60 : continue  # 60점보다 작은 요소면 맨 처음으로 돌아감.
    print("{0} Student is Pass.".format(number + 1))  # 60점 이상인 요소만 출력됨.
    
# 출력 화면
1 Student is Pass.
3 Student is Pass.
5 Student is Pass.

결과가 동일하게 출력됨을 확인할 수 있다.

<< for문과 range 함수를 사용하여 구구단 출력 >>

앞서 알아본 for문과 range 함수를 이용하면 몇 줄의 소스 코드로 구구단을 출력할 수 있다.

for i in range(2, 10):  # 2단부터 9단까지 (첫번째 for문)
    for j in range(1, 10):  # 숫자 1부터 9까지(두번째 for문)
        print(i*j, end=' ')  # i와 j를 곱한 값을 출력. 자세한 건 아래에서 설명.
    print('')
    
# 출력 화면
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45
6 12 18 24 30 36 42 48 54
7 14 21 28 35 42 49 56 63
8 16 24 32 40 48 56 64 72
9 18 27 36 45 54 63 72 81

위의 코드에서 for문이 두 번 사용됐다. 해당 중첩 반복문의 Logic을 정리하면 아래와 같다.

  1. 첫 번째 for문에서 2부터 9까지 숫자가 차례로 i에 대입.(2단부터 9단까지 설정 단계)
  2. i가 대입되어 있을 동안 j를 1부터 9까지 차례로 대입함.
    예를 들면, i = 2일 동안 j에 1부터 9까지 대입되는 것.
  3. print(i * j), 즉, i와 j를 곱한 값이 출력됨
  4. 다시 1로 돌아가서 다음 i 값이 대입된 후 2, 3 반복

해당 Logic을 도식화하여 나타내면 아래의 그림과 같다.

중첩 반복문이 작동하는 Logic

for i in range(2, 10):
    for j in range(1, 10):
        print(i*j, end=' ')
    print('')

다시 해당 코드로 돌아와서 print문의 end 파라미터와 print('')의 역할에 대해 살펴보자.

파이썬에서 print문은 추후 함수 파트에서 조금 더 자세히 다룰 예정이다. 지금은 간단하게만 살펴보자. 파이썬의 print문에서는 end parameter(끝 문자를 지정하는 매개변수)가 개행 문자(\n)로 지정되어 있다. (print 함수가 한 번 실행되면 자동으로 개행이 되게끔 하는 구조!) 따라서 print(i*j)만 수행할 경우 아래와 같이 모든 결과가 한 줄에 하나씩 출력된다.

for i in range(2, 10):
    for j in range(1, 10):
        print(i*j)

# 출력 화면
2
4
6
8
10
12
14
16
18
3
…

이때, end parameter를 바꿈으로써 원하는 결과를 다음 줄로 넘기지 않고 그 줄에 계속 출력하게 할 수 있다. 해당 프로그램에서는 end parameter를 end = " "와 같이 공백 문자(spacebar)로 지정하고 있다. 이와 같은 코드를 적용했을 때는, print문이 한 번 실행되면 띄어쓰기가 한 칸 되는 구조라고 생각하면 된다. 출력 결과를 확인해보자.

for i in range(2, 10):
    for j in range(1, 10):
        print(i*j, end=' ')  # end parameter를 ' '(spacebar)로 지정

프로그램 실행 결과 화면

이번에는 구구단 별(2번째 for문이 끝날 때마다) 줄을 구분해주고 싶다. 따라서 이번에는 2번째 for문이 완전히 끝나자마자 print('')를 넣어 줬다. 공백 문자(null)를 출력함과 동시에 print 함수가 실행되며 자동으로 개행이 되기 때문이다. 이때 코드와 출력 결과는 아래와 같다.

for i in range(2, 10):
    for j in range(1, 10):
        print(i*j, end=' ')
    print('')  # 두 번째 반복문이 완전히 끝난 후 해당 코드 실행 -> 구구단 별 개행 가능

# 출력 화면
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81

[ 리스트 내포(list comprehension) 사용 ]

리스트 안에 for문을 포함하여 리스트 내포(list comprehension)를 사용할 수 있다. 먼저, a 리스트의 각 항목에 3을 곱한 결과를 result 리스트에 담는 예제 코드는 아래와 같이 쓸 수 있다.

a = [1, 2, 3, 4]  # 리스트를 a 변수로 선언
result = []  # 결과를 담을 빈 리스트 선언
for num in a:  # num 변수에 a의 요소를 하나씩 넣으며 반복문 동작.
    # 리스트의 맨 끝에 요소를 추가하는 append 함수 사용.
    # 기억 잘 안 나시면 https://bing-su-b.tistory.com/66 참고 ㄱ-ㄱ
    result.append(num*3)  # num*3 연산 결과를 result 리스트에 추가  
print (result)  # 최종 result 리스트 출력

# 출력 화면
[3, 6, 9, 12]

이를 리스트 내포를 사용하면 다음과 같이 간단하게 코드를 작성할 수 있다.

a = [1, 2, 3, 4]
result = [num*3 for num in a]  # 리스트 내포 사용
print(result)  # 최종 result 리스트 출력

# 출력 화면
[3, 6, 9, 12]

만약 [1, 2, 3, 4] 중 짝수에만 3을 곱하여 담고 싶다면 아래와 같이 리스트 내포 안에 if 조건문을 사용할 수도 있다.

a = [1, 2, 3, 4]
result = [num*3 for num in a if num%2 == 0]  # 리스트 내포 안에 조건문 사용
print(result)  # 최종 result 리스트 출력

# 출력 화면
[6, 12]

정리해서 리스트 내포의 일반적인 문법을 정리하면 아래와 같다. if문은 필요하지 않다면 생략할 수 있다.

[(Expression) for (Contents) in (Iterable_Object) if (Condition)]

조금 복잡하긴 하지만, for문을 2개 이상 쓰는 것도 가능은 하다. (굳이..?) 문법을 정리하면 아래와 같다.

[(Expression) for (Content1) in (Iterable_Object1) if (Condition1)
              for (Content2) in (Iterable_Object2) if (Condition2)
              …
              for (ContentN) in (Iterable_ObjectN) if (ConditionN)]

만약 구구단의 모든 결과를 리스트에 담고 싶은 경우에도 리스트 내포를 사용하여 표현할 수 있다.

result = [x*y for x in range(2, 10)
          for y in range(1, 10)]
print(result)

프로그램 실행 화면

지금까지 if문, while문, for문 세 가지 제어문에 대해 다뤘다. while문과 for문은 실제로 유사하다. 둘을 서로 바꿔 쓸 수 있는 경우도 많으니 잘 알아두도록 하자.

반응형
LIST

관련글 더보기

댓글 영역