Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

7 for 반복문

Updated: 10 mrt 2026

반복 명령문을 이용하면 지정된 명령문을 반복 실행시킬 수 있다. 파이썬은 세 가지 방식으로 명령문을 반복시킬 수 있다.

  • for 반복문

  • while 반복문

  • 재귀 함수

여기서는 for 반복문을, 이어지는 장에서는 while 반복문의 기초 활용법을 소개한다. 반면에 재귀 함수는 다루지 않으며 대신 (코딩알지) 재귀 함수를 읽어볼 것을 추천한다.

for 반복문은 문자열, 리스트 등 모음 자료형의 값에 포함된 모든 항목을 대상으로 동일한 작업을 실행하고자 할 때 활용된다. 형식은 다음과 같다.

for 변수 in 리스트 또는 문자열:
    명령문

for ...가 쓰여진 행의 끝에 콜론 : 이 사용되고 그 아래에 있는 명령문은 들여쓰기 되었음에 주의한다. 들여쓰기된 명령문이 for 반복문의 본문이다.

for 반복문이 문자열 또는 리스트에 대해 작동하는 과정을 간단하게 정리하면 다음과 같다.

  • 변수리스트 또는 문자열에 포함된 항목을 0번 인덱스 위치의 항목에서부터 차례대로 오른쪽으로 이동하며 항목을 가리킴.

  • 변수가 현재 가리키고 있는 항목을 대상으로 지정된 명령문 실행

  • 지정된 변수에 대해 명령문의 실행이 완료되면 변수은 다음 항목을 가리키게 됨.

  • 변수가 더 이상 가리킬 항목이 없을 때까지 위 과정 반복

7.1리스트와 for 반복문

아래 코드는 one2five에 포함된 항목을 차례대로 출력한다.

one2five = [1, 2, 3, 4, 5]

for item in one2five:
    print(item)
1
2
3
4
5

반면에 아래 코드는 one2five에 포함된 항목을 차례대로 더한 결과를 계산하여 출력한다.

one2five = [1, 2, 3, 4, 5]

sum_list = 0 

for item in one2five:
    sum_list = sum_list + item

print("1부터 5까지 정수의 합:", sum_list)
1부터 5까지 정수의 합: 15

코드에 포함된 아래 for 반복분이 실행되면 item 변수는 먼저 0번 인덱스의 항목인 1을 가리킨다.

for item in one2five:
    sum_list += item

따라서 sum_list가 1을 가리키게 되고 다시 반복문의 본문의 처음으로 돌아간다. 이제 item은 1번 인덱스 항목인 2를 가리키고 반복문의 본문을 다시 실행한다.

이 과정을 item이 리스트의 마지막 항목은 5를 가리키고 반복문의 본문을 실행할 때까지 반복하면 for 반복문의 실행을 종료하고 다음 명령문으로 넘어가서 그때까지의 누적합을 가리키는 sum_list를 출력한다.

Python Tutor 활용 for 반복문 설명

아래 그림은 위 코드의 for 반복문이 실행되는 순간 선언된 변수들이 가리키는 값을 보여준다. sum_list는 아직 초기화 상태이고 item은 1을 가리키고 있다.

<그림 출처: Python Tutor>

반면에 아래 그림은 for 반복문이 2번 실행되어 sum_list는 3을, item은 2를 가리키고 있음을 보여준다.

<그림 출처: Python Tutor>

반복문이 계속 실행되어 item이 리스트의 마지막 항목인 5를 가리키면 sum_list는 15를 가리키며 반복문이 종료된다. 그러면 다음 명령문인 print(sum_list)가 실행되어 15가 출력된다(아래 그림 참고).

<그림 출처: Python Tutor>

7.2range() 함수

range() 함수는 리스트와 매우 유사한 값을 생성한다. 예를 들어, range(10)는 0부터 10 이전까지 정수, 즉 0부터 9까지의 정수를 포함하는 리스트와 유사한 값을 생성한다.

range(10)
range(0, 10)

0을 첫째 인자로, 10을 둘째 인자로 사용해도 동일한 모양의 값을 생성한다.

range(0, 10)
range(0, 10)

range() 함수가 생성하는 값의 자료형은 range 이다.

type(range(10))
range

그런데 range(10)의 내부를 바로 보여주지는 않는다.

print(range(10))
range(0, 10)

range 자료형의 값이 내부를 바로 보여주지 않는 이유는 여기서는 설명하지 않는다. 대신 (코딩알지) 이터러블, 이터레이터, 제너레이터를 읽어볼 것을 권장한다. 대신 리스트로의 형변환을 통해 range 자료형의 값에 포함되는 항목들을 확인할 수 있다.

list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

range() 함수와 for 반복문

range() 함수는 for 반복문에서 리스트 대신에 매우 유용하게 활용된다. 예를 들어 아래 코드는 range(10)이 리스트 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 대신 사용될 수 있음을 보여준다. 이유는 item 변수에 0부터 9까지의 정수가 차례대로 할당되기 때문이다.

for item in range(10):
    print("item에 할당된 값:", item)
item에 할당된 값: 0
item에 할당된 값: 1
item에 할당된 값: 2
item에 할당된 값: 3
item에 할당된 값: 4
item에 할당된 값: 5
item에 할당된 값: 6
item에 할당된 값: 7
item에 할당된 값: 8
item에 할당된 값: 9

range() 함수의 인자

range() 함수는 최소 하나에서 최대 세 개의 위치 인자를 받으며, 인자의 개수에 따라 각 인자의 역할이 정해진다.

경우 1: 한 개의 인자

range(10)range(0, 10)과 동일한 모양의 값을 생성한다고 말했듯이 하나의 인자만 사용하면 첫째 인자가 0인 두 개의 인자를 사용하는 경우와 동일하다.

경우 2: 두 개의 인자

range() 함수가 표현하는 구간의 시작을 0이 아닌 다른 정수로 하려면 반드시 두 개의 인자를 사용해야 한다. 예를 들어, 아래 코드는 1부터 10까지의 정수로 구성된 리스트에 해당하는 값을 계산한다.

one2ten_range = range(1, 11)

실제로 리스트로 형변환하면 2부터 10까지의 정수를 포함한 리스트로 계산된다.

list(one2ten_range)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

위 사실을 이용하면 1부터 10까지의 정수의 합을 계산하는 코드를 아래처럼 for 반복문과 range() 함수를 이용하여 간단하게 구현할 수 있다.

sum = 0
for num in range(1, 11):
    sum += num
    
print("1부터 10까지 정수의 합:", sum)
1부터 10까지 정수의 합: 55

경우 3: 세 개의 인자

range() 함수에 세 개의 인자를 사용하면 첫째, 둘째 인자의 의미는 이전과 동일하다. 반면에 셋째 인자는 보폭을 가리킨다. 예를 들어 아래 코드는 1부터 9까지의 정수 중에서 홀수만을 대상으로 하는 리스트를 생성한다. 이유는 보폭이 2로 지정되었기에 1부터 시작해서 1씩이 아닌 2씩 증가시켜 생성되는 값, 즉 홀수들만을 range 자료형의 값에 포함시키기 때문이다.

list(range(1, 10, 2))
[1, 3, 5, 7, 9]

보폭을 인자로 사용하려면 반드시 세 개의 인자를 사용해야 한다. 예를 들어 0부터 10까지의 짝수로 구성된 리스트에 포함시키려면 다음과 같이 한다.

list(range(0, 11, 2))
[0, 2, 4, 6, 8, 10]

두 개의 인자를 사용할 때와는 다르게 첫째 인자가 0이어도 반드시 명시해야 한다. 그렇지 않으면 다음과 같이 엉뚱한 결과를 얻게 된다.

list(range(11, 2))
[]

음의 보폭

바로 앞서 언급한 코드는 구간의 시작이 끝보다 크다. 이런 경우 보폭을 지정하지 않거나 양수로 지정하면 아무런 값도 포함되지 않는다.

list(range(11, 2))  # list(range(11, 2, 1)) 과 동일
[]
list(range(11, 2, 2))
[]

이유는 11에서부터 1씩 또는 2씩 커지면서 2 이전까지의 구간에 속하는 정수는 없기 때문이다. 하지만 음의 보폭을 지정하면 크기가 작아지는 정수들을 항목으로 갖는다.

예를 들어 아래 코드는 11에서부터 0 이전까지, 즉 1까지의 정수 중에서 홀수만을 항목으로 갖는 리스트를 반환한다. 단, 구간의 끝이 둘째 인자의 이전인데 이때 이전의 의미는 보폭이 양의 정수인지, 음의 정수인지에 따라 달라짐에 유의한다.

list(range(11, 0, -2))
[11, 9, 7, 5, 3, 1]

음의 보폭을 갖는 경우에도 for 반복문을 적용하는 방식은 달라지지 않는다. 아래 코드는 11부터 0까지의 홀수를 역순으로 출력한다.

for i in range(11, 0, -2):
    if i % 2 == 1:
        print(f"{i}은(는) 홀수")
11은(는) 홀수
9은(는) 홀수
7은(는) 홀수
5은(는) 홀수
3은(는) 홀수
1은(는) 홀수

리스트 대 range() 함수

리스트가 주어졌을 때 for 반복문을 이용하면 리스트 각각의 항목에 대해 동일한 코드를 실행하도록 할 수 있다. 예를 들어, 아래 코드는 2부터 10까지의 짝수들의 합을 계산한다. 리스트 각각의 항목에 대해 반복되는 아래 명령문이 반복된다.

sum = sum + item

즉, sum 변수에 리스트 각각의 항목을 더한 값을 재할당하는 과정을 반복한다.

two2ten_even = [2, 4, 6, 8, 10]

sum = 0
for item in two2ten_even:
    sum = sum + item
    
print("2부터 10까지 짝수들의 합:", sum)
2부터 10까지 짝수들의 합: 30

그런데 2부터 1만까지, 아니 2부터 1억까지의 짝수들의 합을 계산하려면 one2ten_even과 유사한 변수를 선언하기 위해 항목을 5천 개 또는 5천만 개를 갖는 리스트를 먼저 표현해야 한다. 하지만 이런 일을 사람이 직접 타이핑하기에는 매우 지난하거나 불가능하다.

파이썬을 포함한 대부분의 프로그래밍 언어는 이런 경우를 간단하게 처리할 수 있는 기능을 제공한다. 파이썬의 경우엔 range() 함수를 활용한다. 예를 들어 2부터 10까지의 짝수들의 합을 아래와 같이 계산할 수 있다.

sum = 0
for item in range(2, 11, 2):
    sum = sum + item
    
print("2부터 10까지 짝수들의 합:", sum)
2부터 10까지 짝수들의 합: 30

그리고 위 코드에서 하나의 숫자만 수정해서 2부터 1억까지의 짝수들의 합을 계산할 수 있다.

sum = 0
for item in range(2, 100_000_001, 2):
    sum = sum + item
    
print("2부터 1억까지 짝수들의 합:", sum)
2부터 1억까지 짝수들의 합: 2500000050000000

이처럼 임의의 정수 n에 대해 range(n), range(2, n), range(10, n, 3) 등은 일정한 방식으로 특정 구간에 속하는 값들의 모음을 나타낸다는 점에서 리스트와 많이 다르다.

7.3문자열과 for 반복문

문자열에 포함된 문자 각각을 출력하는 코드는 다음과 같다. for 반복문이 실행되는 동안 ichar 변수가 차례대로 '안', '녕', '하', '세', '요' 를 가리키며, 명령문으로 작성된 print(ichar)에 의해 각 글자가 출력된다. print() 함수가 실행될 때마다 줄바꿈이 발생함에 주의한다.

hello = "안녕하세요"

for ichar in hello:
    print(ichar)
안
녕
하
세
요

예제: 영어 모음 알파벳 확인

다음과 같이 영어 알파벳으로 구성된 문자열이 주어졌다.

text = 'Python_Data-Analysis!'

text 문자열에 포함된 모음으로만 구성된 문자열을 다음과 같이 출력하는 코드를 작성하고자 한다.

P는 모음 아님
y는 모음 아님
t는 모음 아님
h는 모음 아님
n는 모음 아님
_는 모음 아님
D는 모음 아님
t는 모음 아님
-는 모음 아님
n는 모음 아님
l는 모음 아님
y는 모음 아님
s는 모음 아님
s는 모음 아님
!는 모음 아님

모음만 모아서 출력: oaaAai

단, 모음 알파벳은 아래 문자열에 포함되어 있다.

vowels='AEIOUaeiou'

답:

아래 코드는text에 포함된 모음만 모으기 위해 for 반복문을 이용한다.

vowels='AEIOUaeiou'

vowel_strings = ''
for char in text:
    if char in vowels:
        vowel_strings += char
        continue
        
    print(f"{char}는 모음 아님")

print()
print(f"모음만 모아서 출력:", vowel_strings)
P는 모음 아님
y는 모음 아님
t는 모음 아님
h는 모음 아님
n는 모음 아님
_는 모음 아님
D는 모음 아님
t는 모음 아님
-는 모음 아님
n는 모음 아님
l는 모음 아님
y는 모음 아님
s는 모음 아님
s는 모음 아님
!는 모음 아님

모음만 모아서 출력: oaaAai

7.4continue와 break

continuebreak 명령문은 for 반복문과 나중에 배울 while 반복문과 함께 사용되어 반복 과정을 조절한다.

명령문기능
continue반복문의 처음으로 돌아가서 반복되어야 할 다음 차례를 실행
break반복문을 중지시키고 반복문 다음의 명령문 실행

continue 명령문

continue 명령문은 실행되는 순간 자신을 감싸고 있는 for 반복문의 처음으로 돌아가서 반복되어야 할 다음 차례를 실행한다. 예를 들어 아래 코드는 홀수만 더한 결과를 출력한다.

  • char 변수가 홀수인 경우: 해당 문자 출력한 후에 바로 반복문의 처음으로 돌아감. 따라서 if 조건문 아래에 있는 print() 명령문이 실행되지 않음.

  • char 변수가 짝수인 경우: if 조건문이 실행되지 않고 바로 print() 명령문만 실행됨.

one2five = range(1, 6)

for item in one2five:
    if item % 2 == 1:
        print(item)
        continue
        
    print(f"{item}는 짝수라서 무시")

print(f"짝수는 모두 무시됨")        
1
2는 짝수라서 무시
3
4는 짝수라서 무시
5
짝수는 모두 무시됨

아래 코드는 짝수를 무시하는 성질을 이용하여 홀수만 더한 결과를 출력한다.

  • item 변수가 홀수인 경우: sum_list 변수 업데이터

  • item 변수가 짝수인 경우: 무시

one2five = range(1, 6)

sum_list = 0

for item in one2five:
    if item % 2 ==1:
        sum_list = sum_list + int(item)
        continue

    print(f"{item}는 짝수라서 무시")

print(f"짝수는 모두 무시됨")
print(f"1부터 5까지 홀수들의 합:", sum_list)
2는 짝수라서 무시
4는 짝수라서 무시
짝수는 모두 무시됨
1부터 5까지 홀수들의 합: 9

break 명령문

break 명령문은 실행되는 순간 자신을 감싸고 있는 for 반복문을 중지시키고 반복문 다음의 명령문으로 넘어가도록 한다. 예를 들어 아래 코드는 item 변수가 4를 가리키는 순간 for 반복문의 실행을 중단하고 이어지는 print() 명령문으로 바로 넘어간다.

  • item 변수가 4보다 작은 정수를 가리키는: 해당 문자 출력

  • item 변수가 4 이상인 정수를 가리키는 경우: break 명령문이 실행되어 for 반복문의 실행을 중단시킴. 즉, 4와 5의 경우는 전혀 실행되지 않음.

one2five = range(1, 6)

for item in one2five:
    if item >= 4:
        break
        
    print(item)
        
print(f"1부터 {int(item)-1}까지만 반복문이 실행됨!")
1
2
3
1부터 3까지만 반복문이 실행됨!

아래 코드는 4 이상인 정수는 취급되지 않는 성질을 이용하여 1부터 3까지의 정수만 더한 결과를 출력한다.

  • item 변수가 4보다 작은 정수를 가리키는 경우: sum_list 변수 업데이터

  • item 변수가 4 이상인 정수를 가리키는 경우: 취급되지 못함.

one2five = range(1, 6)

sum_list = 0

for item in one2five:
    if item >= 4: # 4 이상이면 중단
        break

    sum_list = sum_list + int(item)
    
print(f"1부터 {int(item)-1}까지 정수의 합:", sum_list)
1부터 3까지 정수의 합: 6

continuebreak 영향 범위

continuebreak 명령문은 자신을 포함한 for 실행에만 영항을 준다.

예를 들어 아래 코드는 n이 12 또는 13을 가리킬 때 n의 소수 여부에 따라 소수면 소수임을 확인하는 문장을, 아니면 작은 수들의 곱으로 계산되는 여러 방식을 화면에 보여준다.

양의 정수가 소수가 되려면 2보다 크고 자신보다 작은 모든 정수에 대해 배수가 아니어야 하는데 이 사실을 확인하기 위해 for 반복문을 이용한다.

  • is_prime 변수: 처음에 True를 가리키다가 n을 나누는 2보다 큰 정수가 확인되는 순간 False로 변하게 되어 n이 소수가 아님을 기억한다. 이후 continue 명령문에 의해 n을 나누는 다른 경우를 확인한다.

  • for 반복문의 실행중에 is_prime이 가리키는 값이 변하지 않았다면 n이 소수임 밝힌다.

for n in [12, 13]:
    print(f"n={n}일때:")
    is_prime = True # 이 값이 계속 유지되면 소수임
    for x in range(2, n):
        if n % x == 0:
            is_prime = False
            print("-", n, "=", x, "*", n//x)
            continue

    if is_prime:
        print(n, "은(는) 소수다.")
    else:
        print(" ", n, "은(는) 소수가 아니다.")
        
    print()
n=12일때:
- 12 = 2 * 6
- 12 = 3 * 4
- 12 = 4 * 3
- 12 = 6 * 2
  12 은(는) 소수가 아니다.

n=13일때:
13 은(는) 소수다.

반면에 아래 코드는 소수가 아닐 때 하나의 곱셈식만 출력한다.

for n in [12, 13]:
    print(f"n={n}일때:")
    is_prime = True # 이 값이 계속 유지되면 소수임
    for x in range(2, n):
        if n % x == 0:
            is_prime = False
            print("-", n, "=", x, "*", n//x)
            break

    if is_prime:
        print(n, "은(는) 소수다.")
    else:
        print(" ", n, "은(는) 소수가 아니다.")
        
    print()
n=12일때:
- 12 = 2 * 6
  12 은(는) 소수가 아니다.

n=13일때:
13 은(는) 소수다.

7.5예제

예제 1

1에서 10까지의 정수 중에서 3의 배수가 아닌 정수만 출력하는 코드를 작성하라.

힌트: 리스트 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], for 반복문 활용, 논리/비교 연산자 활용

답:

1에서 10까지의 정수를 리스트로 선언한다.

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

num 변수가 가리키는 값이 3의 배수가 아닐 때 참이되는 논리식은 다음과 같다.

num % 3 != 0

아래 코드는 one2ten 리스트에 for 반복문을 적용해서 3의 배수가 아닌 정수만 화면에 출력한다.

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

for num in one2ten:
    if num % 3 != 0:
        print(num, end=' ')
1 2 4 5 7 8 10 

num 변수가 가리키는 값이 3의 배수가 아닐 때 참이되는 논리식은 다음과 같이 not 논리 연산자를 이용할 수도 있다.

not num % 3 == 0

따라서 아래 코드도 동일한 결과를 생성한다.

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

for num in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
    if not num % 3 == 0:
        print(num, end=' ')
1 2 4 5 7 8 10 

예제 2

1에서 10까지의 정수 중에서 3의 배수 또는 7의 배수를 모두 출력하는 코드를 작성하라.

힌트: 리스트 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], for 반복문 활용, 논리/비교 연산자 활용

답:

num이 가리키는 값이 3의 배수 또는 7의 배수인 경우에만 num을 출력하고자 하면 아래 표현식을 이용한다.

num % 3 == 0 or num % 7 == 0

이제 num을 1부터 10까지의 정수를 차례대로 가리키도록 하면서 if 조건문을 이용하면 3의 배수 또는 7의 배수를 모두 출력할 수 있다. 아래 코드가 위 내용을 정리한다.

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

for num in one2ten:
    if num % 3 == 0 or num % 7 == 0:
        print(num, end=' ')
3 6 7 9 

예제 3

1부터 10까지의 정수 중에서 홀수들의 합을 계산하라. 단, 1부터 10까지의 정수로 구성된 리스트에 for 반복문을 적용한다.

답:

먼저 1부터 10까지의 정수로 구성된 리스트를 가리키는 변수 one2ten을 선언한다.

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

앞서 1부터 5까지의 합을 계산한 프로그램과 거의 비슷하게 프로그램을 작성할 수 있다.

sum_list = 0
for item in one2five:
    sum_list += item

다만 item이 가리키는 항목이 홀수일 때만 sum_list에 더한다는 점이 다르다. item이 가리키는 값이 홀수인지 여부를 판단하는 표현식은 item % 2 == 1이며, 홀수일 때만 sum_list에 더하는 코드는 다음과 같다.

if item % 2 == 1:
    sum_list += item

정리하면 아래 프로그램을 이용하여 1부터 10까지 정수 중에서 홀수들의 합을 계산할 수 있다.

odd_sum = 0

for num in one2ten:
    if num % 2 == 1: 
        odd_sum += num

print(odd_sum)
25

1부터 10까지의 정수 중에서 홀수들의 합이 25로 계산된다. 그런데 위 코드가 정말로 1, 3, 5, 7, 9의 합을 계산했는지 결과만으로는 알 수 없다. 이를 확인하기 위해 코드를 실행할 때 sum_list에 더해지는 수를 함께 출력하도록 프로그램을 수정해보자.

홀수인 경우 화면에 출력되도록 print() 함수를 이용한다. 단, end=" " 키워드 인자를 이용하여 홀수들의 출력이 한 줄에 이루어지도록 하였다. 끝에서 둘쨋줄의 print() 함수는 마지막 줄의 출력을 구분하는 줄바꿈용으로 사용된다.

odd_sum = 0

print("더해지는 수:", end=" ")
for num in one2ten:
    if num % 2 == 1: 
        print(num, end=" ")
        odd_sum += num   

print("")
print("1부터 10까지의 정수 중에서 홀수들의 합:", odd_sum)
더해지는 수: 1 3 5 7 9 
1부터 10까지의 정수 중에서 홀수들의 합: 25

예제 4

1부터 9까지의 정수를 항목으로 포함한 리스트가 다음과 같다.

one2nine = list(range(1, 10))

1부터 9까지의 정수를 대상으로 3의 배수가 아니면 3의 배수가 아님을 출력하는 코드를 작성하라. 또한 7 이상의 정수는 무시해야 한다.

힌트: for 반복문, continue, break 명령문 활용

답:

one2nine 리스트를 대상으로 for 반복문을 실행한다. 그러면서 3의 배수 항목은 건너뛰도록 하기 위해 continue 명령문을, 7 항목을 가리키는 순간 break 명령문을 실행하도록 한다.

for item in one2nine:
    if item % 3 == 0:
        continue
        
    print(f"{item}은(는) 3의 배수 아님.")
    
    if item == 7:
        break

print()
print(f"item 변수가 1부터 {item}까지만 반복문이 실행되었음!")
1은(는) 3의 배수 아님.
2은(는) 3의 배수 아님.
4은(는) 3의 배수 아님.
5은(는) 3의 배수 아님.
7은(는) 3의 배수 아님.

item 변수가 1부터 7까지만 반복문이 실행되었음!

예제 5

다음과 같이 영어 알파벳으로 구성된 문자열이 주어졌다.

text = 'Python_Data-Analysis!'

text 문자열에 포함된 자음으로만 구성된 문자열을 다음과 같이 출력하는 코드를 작성하라.

포함된 모음: o_aa-Aai!
포함된 자음: PythnDtnlyss

힌트: isalpha() 메서드 활용

단, 모음 알파벳은 아래 문자열에 포함되어 있다.

vowels='AEIOUaeiou'

답:

아래 코드는text에 포함된 자음만 모으기 위해 for 반복문을 이용한다.

vowels='AEIOUaeiou'

print('기타 문자:', end=' ')
consonant_strings = ''
for char in text:
    if char not in vowels and char.isalpha():
        consonant_strings += char
        continue

    print(char, end='')
        
print()
        
print("포함된 자음:", consonant_strings)
기타 문자: o_aa-Aai!
포함된 자음: PythnDtnlyss

예제 6

문자열의 find() 메서드가 작동하는 방식을 이해하기 위한 예제다. 먼저 두 개의 문자열을 지정한다.

word1 = 'chukachuka'
word2 = 'uka'

word2 변수가 가리키는 문자열이 word1 문자열에 처음 사용되기 시작하는 곳의 인덱스를 찾는 코드를 작성하라.

힌트: for 반복문, 문자열 슬라이싱, break 명령문 활용

답 1:

uka는 2번 인덱스부터 시작한다. 따라서 2번부터 거기에 uka 문자열의 길이인 3만큼 큰 구간에 대해 슬라이싱을 적용하면 uka가 생성된다.

word1[2:2+3]
'uka'

그런데 원 문장이 아주 길고 찾는 부분 문자열이 어디 있는지 한눈에 알아볼 수 없을 때는 2뿐만 아니라 모든 인덱스에 대해 찾고자 하는 부분문자열의 길이만큼 슬라이싱을 해서 확인해야 한다.

지금까지의 설명을 코드로 구현하기 위해 필요한 변수들을 사용한다.

  • location: 찾는 부분문자열이 시작하는 곳의 인덱스. 찾지 못하는 경우 -1로 지정.

  • pos: 문자열 대상으로 for 반복문이 실행될 때 각 문자의 인덱스에 해당.

  • found: 부분 문자열이 찾아졌는지 여부

location = -1
pos = 0
found = False

for char in word1:
    if word2 == word1[pos:pos+len(word2)] and not found:
        location = pos
        found = True
        
    pos += 1
        
print(f"{word2}가 시작되는 인덱스:", location)
uka가 시작되는 인덱스: 2

답 2:

break 명령문을 활용하면 보다 간단하게 코드를 구현할 수 있다.

location = -1
pos = 0

for char in word1:
    if word2 == word1[pos:pos+len(word2)]:
        location = pos
        break
        
    pos += 1
        
print(f"{word2}가 시작되는 인덱스:", location)
uka가 시작되는 인덱스: 2

예제 7

for 반복문을 이용하여 구구단을 출력하고자 한다. 반복문을 위해 아래 변수를 이용한다.

one2nine = range(1, 10)

사용자로부터 1부터 9사이의 정수를 입력 받은 후 입력된 정수의 배수에 해당하는 구구단만 화면에 출력하는 코드를 작성하라. 예를 들어, 사용자가 3을 입력하면 3의 배수인 3, 6, 9에 대한 구구단만 아래와 같이 출력해야 한다. 또한 for 반복문과 함께 continue 명령문을 구구단 출력에 이용해야 하며, 곱셈 결과는 오른쪽으로 정렬되어야 한다.

  • 3을 입력하는 경우

단수를 입력하세요: 3

3의 배수 구구단 출력

3단

3 * 1 =  3
3 * 2 =  6
3 * 3 =  9
3 * 4 = 12
3 * 5 = 15
3 * 6 = 18
3 * 7 = 21
3 * 8 = 24
3 * 9 = 27

6단

6 * 1 =  6
6 * 2 = 12
6 * 3 = 18
6 * 4 = 24
6 * 5 = 30
6 * 6 = 36
6 * 7 = 42
6 * 8 = 48
6 * 9 = 54

9단

9 * 1 =  9
9 * 2 = 18
9 * 3 = 27
9 * 4 = 36
9 * 5 = 45
9 * 6 = 54
9 * 7 = 63
9 * 8 = 72
9 * 9 = 81
  • 4를 입력하는 경우

단수를 입력하세요: 4

4의 배수 구구단 출력

4단

4 * 1 =  4
4 * 2 =  8
4 * 3 = 12
4 * 4 = 16
4 * 5 = 20
4 * 6 = 24
4 * 7 = 28
4 * 8 = 32
4 * 9 = 36

8단

8 * 1 =  8
8 * 2 = 16
8 * 3 = 24
8 * 4 = 32
8 * 5 = 40
8 * 6 = 48
8 * 7 = 56
8 * 8 = 64
8 * 9 = 72

힌트: for 반복문을 중첩해서 활용

답:

for 반복문을 중첩해서 사용해야 한다.

  • 바깥쪽 for i_th in one2nine 형식의 반복문: 1단부터 9단까지 진행

  • 안쪽 for j_th in one2nie 형식의 반복문: 각각의 단계에서 1부터 9까지의 곱 실행

이때 입력값의 배수가 아닌 단은 무시해야 하기에 바깥쪽 for i_th in one2nine 반복문에서 i_th가 입력값의 배수가 아닌 경우는 continue 명령문을 이용하여 무시하고 건너뛰도록 한다.

  • 3을 입력하는 경우

one2nine = range(1, 10)

table_index = int(input("단수를 입력하세요: "))

print(f"\n{table_index}의 배수 구구단 출력\n")
for i in one2nine:
    if i % table_index != 0:
        continue
        
    print(f"{i}단\n")
    for j in one2nine:
        print(f"{i} * {j} = {i * j:>2d}") # 곱셈 오른쪽으로 정렬
        
    print()
단수를 입력하세요: 3

3의 배수 구구단 출력

3단

3 * 1 =  3
3 * 2 =  6
3 * 3 =  9
3 * 4 = 12
3 * 5 = 15
3 * 6 = 18
3 * 7 = 21
3 * 8 = 24
3 * 9 = 27

6단

6 * 1 =  6
6 * 2 = 12
6 * 3 = 18
6 * 4 = 24
6 * 5 = 30
6 * 6 = 36
6 * 7 = 42
6 * 8 = 48
6 * 9 = 54

9단

9 * 1 =  9
9 * 2 = 18
9 * 3 = 27
9 * 4 = 36
9 * 5 = 45
9 * 6 = 54
9 * 7 = 63
9 * 8 = 72
9 * 9 = 81

  • 4를 입력하는 경우

one2nine = range(1, 10)

table_index = int(input("단수를 입력하세요: "))

print(f"\n{table_index}의 배수 구구단 출력\n")
for i in one2nine:
    if i % table_index != 0:
        continue
        
    print(f"{i}단\n")
    for j in one2nine:
        print(f"{i} * {j} = {i * j:>2d}") # 곱셈 오른쪽으로 정렬
        
    print()
단수를 입력하세요: 4

4의 배수 구구단 출력

4단

4 * 1 =  4
4 * 2 =  8
4 * 3 = 12
4 * 4 = 16
4 * 5 = 20
4 * 6 = 24
4 * 7 = 28
4 * 8 = 32
4 * 9 = 36

8단

8 * 1 =  8
8 * 2 = 16
8 * 3 = 24
8 * 4 = 32
8 * 5 = 40
8 * 6 = 48
8 * 7 = 56
8 * 8 = 64
8 * 9 = 72

예제 8

사용자로부터 1부터 9사이의 정수를 입력 받은 후 입력된 정수의 배수에 해당하는 구구단만 지정된 형식으로 화면에 출력하는 코드를 작성하라. 예를 들어, 사용자가 3을 입력하면 3의 배수인 3, 6, 9에 대한 구구단만 아래와 같이 출력해야 한다. 또한 for 반복문과 함께 continue, break 명령문을 구구단 출력에 이용해야 하며, 곱셈 결과는 오른쪽으로 정렬되어야 한다.

  • 3을 입력하는 경우

단수를 입력하세요: 3

3의 배수 구구단 출력

3단

3 * 1 =  3
3 * 2 =  6

6단

6 * 1 =  6
6 * 2 = 12

9단

9 * 1 =  9
9 * 2 = 18
  • 4를 입력하는 경우

단수를 입력하세요: 4

4의 배수 구구단 출력

4단

4 * 1 =  4
4 * 2 =  8
4 * 3 = 12

8단

8 * 1 =  8
8 * 2 = 16
8 * 3 = 24

힌트: for 반복문을 중첩해서 활용

답:

for 반복문을 중첩해서 사용해야 한다.

  • 바깥쪽 for i_th in one2nine 형식의 반복문: 1단부터 9단까지 진행

  • 안쪽 for j_th in one2nie 형식의 반복문: 각각의 단계에서 1부터 9까지의 곱 실행

이때 입력값의 배수가 아닌 단은 무시해야 하기에 바깥쪽 for i_th in one2nine 반복문에서 i_th가 입력값의 배수가 아닌 경우는 continue 명령문을 이용하여 무시하고 건너뛰도록 한다.

더 나아기 안쪽 for j_th in one2nie에서 j_th가 입력값보다 작을 때까지만 곱셈을 실행하도록 해야한다. 이를 위해 break 명령문을 활용한다.

  • 3을 입력하는 경우

one2nine = range(1, 10)

table_index = int(input("단수를 입력하세요: "))

print(f"\n{table_index}의 배수 구구단 출력\n")
for i in one2nine:
    if i % table_index != 0:
        continue
        
    print(f"{i}단\n")
    for j in one2nine:
        if j >= table_index:
            break
        print(f"{i} * {j} = {i * j:>2d}")
        
    print()
단수를 입력하세요: 3

3의 배수 구구단 출력

3단

3 * 1 =  3
3 * 2 =  6

6단

6 * 1 =  6
6 * 2 = 12

9단

9 * 1 =  9
9 * 2 = 18

  • 4를 입력하는 경우

one2nine = range(1, 10)

table_index = int(input("단수를 입력하세요: "))

print(f"\n{table_index}의 배수 구구단 출력\n")
for i in one2nine:
    if i % table_index != 0:
        continue
        
    print(f"{i}단\n")
    for j in one2nine:
        if j >= table_index:
            break
        print(f"{i} * {j} = {i * j:>2d}")
        
    print()
단수를 입력하세요: 4

4의 배수 구구단 출력

4단

4 * 1 =  4
4 * 2 =  8
4 * 3 = 12

8단

8 * 1 =  8
8 * 2 = 16
8 * 3 = 24

예제 9

369게임은 사용자로부터 양의 정수 n이 입력되었을 때 1부터 n까지의 자연수를 다음 규칙에 따라 출력한다.

  • 3의 배수이거나 1의 자릿수가 3인 수일 경우, 해당하는 수를 출력하는 대신 문자열 을 출력

  • 나머지 수는 그대로 출력

예를 들어, n이 15인 경우 다음과 같이 출력된다.

1 2 짝 4 5 짝 7 8 짝 10 11 짝 짝 14 짝

369게임을 진행하는 코드를 구현하여 n이 30일 때의 출력 결과를 확인하라.

힌트: range() 함수, for 반복문, % 연산자, print() 함수의 end 키워드 인자 활용

답:

양의 정수 n이 주어졌다고 가정하자. 그러면 n보다 같거나 작은 양의 정수를 가리키는 num에 대해 논리식 num % 10 == 3num을 10으로 나눴을 때의 나머지가 3일 때 참이 되는데 이는 num의 일의 자릿수가 3이라는 의미이기도 하다. 따라서 "3의 배수이거나 1의 자릿수가 3인 수일 경우"를 아래 논리식으로 표현할 수 있다.

num % 3 == 0 or num % 10 == 3

range(1, n+1) 구간의 정수에 대해 아래 논리식이 참이면 짝을, 아니면 해당 정수를 출력하도록 하면 된다. 이를 위해 아래 함수처럼 for 반복문을 이용한다.

n = int(input("양의 정수 하나 입력:"))

for num in range(1, n+1):
    if num % 3 == 0 or num % 10 == 3:
        print('짝', end=' ')
    else:
        print(num, end=' ')
양의 정수 하나 입력:30
1 2 짝 4 5 짝 7 8 짝 10 11 짝 짝 14 짝 16 17 짝 19 20 짝 22 짝 짝 25 26 짝 28 29 짝 
n = int(input("양의 정수 하나 입력:"))

for num in range(1, n+1):
    if num % 3 == 0 or num % 10 == 3:
        print('짝', end=' ')
    else:
        print(num, end=' ')
양의 정수 하나 입력:15
1 2 짝 4 5 짝 7 8 짝 10 11 짝 짝 14 짝 

예제 9

range() 함수를 이용하여 2 보다 같거나 큰 양의 정수 n이 인자로 주어지면 2부터 n까지의 짝수들의 합을 반환하는 함수 addition_n()을 선언하라.

답:

아래 addition_n() 함수는 n이 인자로 들어오면 2부터 n까지의 정수를 포함하는 값 range(2, n+1)에 대해 for 반복문을 실행한다.

def addition_n(n):
    sum = 0
    for item in range(2, n+1, 2):
        sum = sum + item

    print("2부터", n, "까지 짝수들의 합:", sum)
addition_n(10)
2부터 10 까지 짝수들의 합: 30
addition_n(100)
2부터 100 까지 짝수들의 합: 2550
addition_n(1000)
2부터 1000 까지 짝수들의 합: 250500
addition_n(100000000)
2부터 100000000 까지 짝수들의 합: 2500000050000000

주의사항

range() 함수를 이용하지 않고 리스트를 이용하여 동일한 기능을 수행하는 함수를 구현할 수는 없다. 이유는 리스트 [2, 4, 6, ..., n] 의 길이가 n에 의존해서 달라지는데 변수 n이 가리키는 값을 모르면 리스트 자체를 선언할 수 없기 때문이다.

7.6연습문제

문제 9

ROT13 은 단어의 각 문자를 13 자리만큼 회전시키는 방식의 간단한 암호 법이다. 문자를 회전한다는 것은 알파벳 상의 위치를 이동한다는 뜻이다. 예를 들어, 'a' 를 3 만큼 이동하면 'd' 가, 'z' 를 1 만큼 이동하면 'a' 가 된다.

다음 하나의 매개변수를 사용하는 encrypt() 함수를 구현하라.

  • word: 영어 문장 문자열

함수의 반환값은 문장에 포함된 모든 영어 알파벳을 13 자리만큼 회전시킨 문자열이다. 단, 모든 문자는 소문자로 변환한다. 또한 [문자열 인덱싱, 슬라이싱](file:///C:/Users/gslee/Documents/GitHub/42H/jupyter-book/_build/html/strings_part2.html)의 예제에서 소개한 ord() 함수와 chr() 함수를 반드시 활용한다.

영어 소문자 알파벳은 총 26개이에 각각의 알파벳 char를 13 자리만큼 회전시키면 ord(char) 값에 따라 다르게 계산된다.

  • 97 <= ord(char) <= 109인 경우, 즉 영어 소문자 'a'부터 'm'까지의 알파벳인 경우: ord(char)에 13을 더해준 값에 해당하는 알파벳

  • 109 <= ord(char) <= 122인 경우, 즉 영어 소문자 'n'부터 'z'까지의 알파벳인 경우: ord(char)에서 13을 빼준 값에 해당하는 알파벳

따라서 모두 소문자로 변환한 다음에 각각의 알파벳을 13 자리만큼 회전시킨 결과로 구성된 문자열 아래 encrypt() 함수로 계산한다.

def encrypt(text):
    encrypted = ""
    
    for char in text.lower():
        if 97 <= ord(char) <= 109:
            encrypted += chr(ord(char) + 13)
        elif 109 < ord(char) <= 122:
            encrypted += chr(ord(char) - 13)
        else:
            encrypted += char
            
    return encrypted       
encrypt('I love python')
'v ybir clguba'
encrypt(encrypt('I love python'))
'i love python'
encrypt('Believe me!')
'oryvrir zr!'

문제 10

소문자와 대문자를 그대로 유지하도록 앞서 선언한 encrypt() 함수를 수정하라.

대소문자에 따라 if ... elif ... else... 조건식을 사용하면 된다. 대문자의 구분은 숫자만 다를 뿐 소문자의 구분과 동일하다.

def encrypt(text):
    encrypted = ""
    
    for char in text:
        if char.isupper():
            if 65 <= ord(char) <= 77:
                encrypted += chr(ord(char) + 13)
            else:
                encrypted += chr(ord(char) - 13)
        elif char.islower():
            if 97 <= ord(char) <= 109:
                encrypted += chr(ord(char) + 13)
            else:
                encrypted += chr(ord(char) - 13)
        else:
            encrypted += char
            
    return encrypted       
encrypt('I love python')
'V ybir clguba'
encrypt(encrypt('I love python'))
'I love python'
encrypt('Believe me!')
'Oryvrir zr!'

문제 11

아래 함수는 양의 정수 n과 함께 호출되면 n x n 모양의 격자무늬를 출력한다.

pm = "+ - - "
ps = "|     "
plus_sign = "+"
pipe_sign = "|"

def print_pm(n):
    print(pm * n + plus_sign)

def print_ps(n):
    ps_line = ps * n + pipe_sign
    print(ps_line, ps_line, sep="\n")

def grid(n):
    for count in range(n):
        print_pm(n)
        print_ps(n)
        count += 1
        
    print_pm(n)
grid(3)
+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +

grid() 함수를 일반화하여 직사각형 모양의 격자무늬를 출력하는 grid_gen() 함수를 구현하라. 사용되는 두 개의 매개 변수와 반환값은 다음과 같아야 한다.

  • n: 세로 격자 칸 개수

  • m: 가로 격자 칸 개수

  • 반환값: n*m

또한, 예를 들어, grid_gen(2, 3) 을 실행하면 아래 모양의 격자를 그려야 한다.

+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +

힌트: grid() 함수에 매개 변수 m을 추가할 때 어느 부분을 수정해야 하는지 알아낸다.

grid(n)이 호출되었을 때 격자 칸의 가로, 세로 개수가 n에 의해 결정된다. 이에 대한 보다 자세한 설명은 (필수 예제) 함수를 참고한다.

  • 가로 격자 칸 개수: print_pm(n)print_ps(n)에서의 n에 의해 결정됨

  • 세로 격자 칸 개수: for count in range(n)에서의 n에 의해 결정됨.

따라서 가로와 세로의 격자 칸 개수를 달리 하려면 앞서 언급된 두 부분에서의 n의 사용을 달리 해야 한다. 아래 코드는 n은 세로 격자 칸 개수를, m은 가로 격자 칸 개수를 지정한다.

pm = "+ - - "
ps = "|     "
plus_sign = "+"
pipe_sign = "|"

def print_pm(m):              # m: 가로 격자 칸 개수
    print(pm * m + plus_sign)

def print_ps(m):
    ps_line = ps * m + pipe_sign
    print(ps_line, ps_line, sep="\n")

def grid_gen(n, m):
    for count in range(n):         # n: 세로 격자 칸 개수
        print_pm(m)
        print_ps(m)
        count += 1
        
    print_pm(m)
    
    return n * m            # 반환값: 격자 칸 수
grid_gen(2, 3)
+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +
|     |     |     |
|     |     |     |
+ - - + - - + - - +
6
grid_gen(3, 5)
+ - - + - - + - - + - - + - - +
|     |     |     |     |     |
|     |     |     |     |     |
+ - - + - - + - - + - - + - - +
|     |     |     |     |     |
|     |     |     |     |     |
+ - - + - - + - - + - - + - - +
|     |     |     |     |     |
|     |     |     |     |     |
+ - - + - - + - - + - - + - - +
15