6) for문 (2)

for와 range함수

 

for문은 range라는 숫자 리스트를 자동으로 만들어 주는 함수와 함께 사용되는 경우가 많다.

  다음은 range함수의 간단한 사용법이다.

 

>>> a = range(10) 
>>> a 
range(0, 10)

 

위에서 보는 것과 같이 range(10)은 0부터 10미만의 숫자 range객체를 만들어 준다.

  시작 번호와 끝 번호를 지정하려면 다음과 같이 해야 한다. 끝 번호는 포함되지 않는다.

 

>>> a = range(1, 11) 
>>> a 
range(1, 11)

 

위처럼 시작 숫자를 정해 줄 수도 있다.

  for와 range를 이용하면 1부터 10까지 더하는 것을 다음과 같이 쉽게 구현할 수 있다.

 

     예 ) 1부터 10까지의 합

 

>>> sum = 0 
>>> for i in range(1, 11): 
. . .     sum = sum + i 
. . . 
>>> print(sum)
55

 

range(1, 11)은 숫자 1부터 10까지의(1이상 11미만의) 숫자를 데이터로 갖는 자료형이다.

  따라서 위의 예에서 i변수에 리스트의 숫자들이 하나씩 차례로 대입되면서 sum = sum + i라는 문장을 수행하게 되어 sum은 최종적으로 55가 되게 된다.

또한 우리가 앞서 살펴 보았던 60점 이상이면 합격인 예제도 range함수를 이용해서 적용시킬 수도 있다. 다음을 보자.

 

#marks3.py 
marks = [90, 25, 67, 45, 80]

for number in range(len(marks)): 
    if marks[number] < 60: continue 
    print("%d번 학생 축하합니다. 합격입니다." % (number+1))

 

  len이라는 함수가 처음 나왔는데 len함수는 리스트의 요소 개수를 돌려주는 함수이다.

따라서 위에서 len(marks)는 5가 될것이고 range(len(marks))는 range(5)가 될 것이다.

  따라서 number변수에는 차례로 0부터 4까지의 숫자가 대입될 것이고 makrs[number]는 차례대로 90, 25, 67, 45, 80이라는 값을 갖게 될 것이다.

 

다양한 for문의 사용

 

>>> a = [(1,2), (3,4), (5,6)] 
>>> for (first, last) in a: 
. . .     print(first + last)
. . . 
3 
7 
11

 

  위의 예는 a리스트의 요소 값이 튜플이기 때문에 각각의 요소들이 자동으로 (first, last)라는 변수에 대입되게 된다.

이것은 이미 살펴보았던 터플을 이용한 변수 값 대입방법과 매우 비슷한 경우이다.

 

>>> (first, last) = (1, 2)

 

for와 range를 이용한 구구단

 

  for와 range함수를 이용하면 단 4줄만으로 구구단을 출력해 볼 수가 있다.

 

>>> 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

 

  위의 예를 보면 for가 두 번 사용되었다. range(2, 10)은 2부터 9까지의 숫자가 차례로 i에 대입된다.

i가 처음 2일 때 두 번째 for 문을 만나게 된다. range(1, 10)은 1부터 10까지의 숫자가 j에 대입되고 그 다음 문장인 print(i*j)를 수행한다.

  따라서 i가 2일 때 2*1, 2*2, 2*3, , , ,2*9 까지 차례로 수행되며 그 값을 출력하게 된다.

그 다음에는 i가 3일 때 역시 2일 때와 마찬가지로 수행될 것이고 i가 9일 때까지 계속 반복되게 된다.

  위에서 print(i*j, end=" "), 처럼 end 파라미터를 넣어준 이유는 해당 결과값을 출력할 때 다음 줄로 넘어가지 않고 그 줄에 계속해서 출력하기 위한 것이다.

그 다음의 print('')은 2단, 3단, , 등을 구분하기 위해서 두 번째 for문이 끝나면 결과 값을 다음 줄부터 출력하게 해주는 문장이다.

 

※ 파이썬 2.7 버전의 경우 위 예제의 print(i*j, end=" ") 대신 print i*j,와 같이 콤마(,)를 마지막에 넣어주어야 한다. (참고: 파이썬 2.7 vs 파이썬 3)

 

  지금껏 우리는 프로그램의 흐름을 제어하는 if, while, for등에 대해서 알아보았다.

독자는 while과 for를 보면서 두 가지가 아주 흡사하다는 느낌을 받았을 것이다.

  실제로 for문을 쓰는 부분을 while로 바꿀 수 있는 경우가 많고 while문을 쓴 부분을 for문으로 바꾸어서 사용할 수 있는 경우가 많다.

 

리스트 내포(List comprehension)

 

리스트 안에 for문을 이용하면 좀 더 편리하고 직관적이게 프로그램을 만들 수 있다. 다음의 예제를 보자.

 

>>> a = [1,2,3,4]
>>> result = []
>>> for num in a:
...     result.append(num*3)
...
>>> print(result)
[3, 6, 9, 12]

 

  위 예제는 a라는 리스트의 각 항목에 3을 곱한 결과를 result라는 리스트에 담는 예제이다.

이것을 리스트 내포를 이용하면 다음과 같이 간단히 해결할 수 있다.

 

>>> result = [num * 3 for num in a]
>>> print(result)
[3, 6, 9, 12]

 

  만약 3을 곱한 수 중 짝수만 담고 싶다면 다음과 같이 할 수 있다.

 

>>> result = [num * 3 for num in a if num % 2 == 0]
>>> print(result)
[6, 12]

 

리스트 내포의 일반적인 문법은 다음과 같다.

 

[표현식 for 항목 in 반복가능객체 if 조건]

 

  위 문법에서 조건식 부분은 위 예제에서 보듯이 생략이 가능하다.

조금 복잡하지만 for문을 2개이상 사용하는 것도 가능하다. for문을 여러개 사용할 경우의 문법은 다음과 같다.

 

[표현식 for 항목1 in 반복가능객체1 if 조건1
        for 항목2 in 반복가능객체2 if 조건2
        ...
        for 항목n in 반복가능객체n if 조건n]

 

  위에서 살펴본 구구단의 모든 결과를 리스트에 담고 싶다면 리스트 내포를 이용하여 아래와 같이 구현할 수 있을 것이다.

 

>>> result = [x*y for x in range(2,10)
...               for y in range(1,10)]
>>> print(result)
[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]

 

예제를 연습해 봅시다