반복문 이해하기

딥러닝견습생·2021년 12월 29일
0

For 문

정해진 횟수만큼 반복한다.

1. 각 언어별 for문 비교

  • C
    for (int i = 0; i < 10; i++)  // 0부터 9까지 증가하면서 10번 반복
    {
        printf("%d\n", i);
    }
    
    >>> Output
    0
    1
    2
    ...
    9
  • C#
    for (int i=0; i<10; i++)  // 0부터 9까지 증가하면서 10번 반복
    {
        Console.WriteLine(i.toString())
    }
    >>> Output
    0
    1
    2
    ...
    9
  • Java
    for (int i=0; i<10; i++)
    {
        System.out.println(i);
    }
    >>> Output
    0
    1
    2
    ...
    9
  • Javascript
    for (let i=0; i<10; i++)
    {
        console.log(i)
    }
    >>> Output
    0
    1
    2
    ...
    9

2. Python 에서의 표현(range 활용)

  • 초기값을 2부터 시작하고 싶다면?
    for i in range(2, 10):
    		print(i)
    
    >>> Output
    2
    3
    ...
    9
  • 건너뛰는건 할 수 없을까?
    for i in range(2, 10, 2):
    		print(i)
    
    >>> Output
    2
    4
    6
    8
  • 거꾸로도 하고 싶은데?
    for i in reversed(range(0, 10, 2)):
    		print(i)
    
    >>> Output
    8
    6
    ...
    0
  • range 뿐만 아니라 list, tuple, dictionary, string 등 제한된 데이터들도 반복 가능..!
    for s in "hi!":
        print(s)
    >>> Output
    h
    i
    !
    
    hello = "hello"  # 문자열도 배열처럼 취급 가능..!
    print(hello[1])
    >>> Output
    e
    
    for i in [1, 2]:
        print(i)
    >>> Output
    1
    2
    
    for i in (4, 6):
        print(i)
    >>> Output
    4
    6
    
    for key in {"a": 1, "b": 2}:
        print(key)
    >>> Output
    a
    b

While 문

정해진 횟수를 특정할 수 없을 때 활용
반복의 조건을 명확히 명시하거나, break 문을 활용해야 한다.

break란?
반복문을 즉시 중단 시킨다.

  • 조건을 부여한다면
    i = 0
    while i < 10:
         print(i)
         i += 1
    
    >>> Output
    0
    1
    ...
    9

Tip!
Python에서 ++ 연산자는 사용할 수 없다.(1씩 증가)
i++ ⇒ i += 1

  • 무한루프에서 break문 활용
    i = 0
    while True:
         print(i)
         i += 1
         if i >= 9:
             break
    
    >>> Output
    0
    1
    ...
    9

반복문은 중첩 할 수 있다

반복문 구문 내 반복문을 정의하면 반복을 중첩 할 수 있다.

for 문으로 구구단을 표현 해보자

for i in range(2, 10):  # 2~9단까지!
    for j in range(1, 10):  # nx1 ~ nx9 까지!
        print(i, "x", j, "=", i*j)

>>> Output
2 x 1 = 2
2 x 2 = 4
...
6 x 3 = 18
6 x 4 = 24
...
9 x 9 = 81

Tip!
print() 문을 사용할 때, 변수와 스트링을 콤마로 연결할 수 있다.

While 문으로 구구단을 표현 해보자

  1. 무한루프로 한다면?
    i, j = 2, 1  # 변수 여러개를 한줄에 선언할 수 있다!
    while True:
        j = 1  # 다음 단으로 넘어갈 때 j 변수는 초기화 되어야 한다.
        while True:
            print(f"{i} x {j} = {i*j}")
            j += 1
            if j > 9:  # nx1 ~ nx9 까지!
                break  # 중첩된 반복문 중단
        i += 1
        if i > 9:  # 9단까지 출력
            break  # 첫 반복문 중단

Tip!
변수를 여러개 선언할 때, 한줄로 선언이 가능하다.
a, b = “a의 값”, “b의 값”
좌변과 우변의 갯수가 일치해야 한다.

Tip!
스트링에 f 인자를 붙이면 변수를 직접 명시하여 사용할 수 있다.
print(i, " x ", j, " = ", ij) vs print(f"{i} x {j} = {ij}")
문자열에 어떤 변수가 어디에 어떻게 쓰였는지 훨씬 직관적이고 짧게 표현이 가능하다

  1. 조건을 명시한다면?
    i, j = 2, 1
    while i < 10:
        j = 1
        while j < 10:
            print(f"{i} x {j} = {i*j}")
            j += 1
        i += 1

break, continue 의 활용

break
반복문을 즉시 중단시킨다

continue
반복문을 중단시키지 않고 건너뛴다

구구단으로 활용법 이해하기

편의상 for문만 사용합니다. while 문도 원리는 동일!

  • break 구구단에서 n x 5 까지만 출력하기
    for i in range(2, 10):
        for j in range(1, 10):
            print(f"{i} x {j} = {i*j}")
            if j >= 5:  # n x 6 이상은 출력하지 않는다.
                break  # break 가 아닌 continue 라면 n x 9 까지 연속해서 출력
    
    >>> Output
    2 x 1 = 2
    ...
    2 x 5 = 10
    3 x 1 = 3
    ...
    9 x 5 = 45
  • continue 구구단에서 짝수단만 출력하기
    for i in range(2, 10):
        if i % 2 != 0:
            continue  # n단이 2로 나눠떨어지지 않는 홀수라면 아래 반복문을 건너뛴다
                      # break를 사용했다면, 2단까지만 출력하고 멈춤
        for j in range(1, 10):
            print(f"{i} x {j} = {i*j}")
    
    >>> Output
    2 x 1 = 2
    ...
    2 x 9 = 18
    4 x 1 = 4
    ...
    8 x 9 = 72

그 외에 알면 도움이 될..?

보통 while은 DB 등에서 Unique Key 등을 생성할 때 활용한다.

ex) 10만개의 중복되지 않는 쿠폰번호를 생성할 때, 랜덤한 문자열이며 중복되지 않아야 한다면?
(반복 횟수를 특정할 수 없을 때! while 문에서 생성한 값을 중복체크한다.)

일반적인 경우엔 for 가 많이 활용 됨.

구구단의 사례에서 처럼 반복문 안에서 if 등으로 멈추고 건너뜀을 제어할 것이 아니라, 애초에 원하는 값만 반복될 수 있도록 하는게 예외도 줄이고 코드 가독성에도 도움이 된다.

  1. 데이터를 정제하고
  2. for 로 돌린다.

List Comprehension 문법 이해하기

range(n) 은 0부터 n-1 까지의 값을 가진다.

list(range(10))

>>> Output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 짝수만 걸러내기
    [i for i in range(10) if i % 2 == 0]  # list(range(0, 10, 2)) 와 동일..하긴..ㅎ..
    
    >>> Output
    [0, 2, 4, 6, 8]

해설
1. [] 리스트로 정의하고
2. [i for i in range(10)] for 문의 i 는 0 ~ 9 까지 열거되고, 이 i 를 배열에 넣어라!
3. 이때, i 에 대한 조건을 부여할 수 있는데, i 를 2로 나누었을 때 나머지값이 0이라면? 라는 조건을 부여한다면
->> [i for i in range(10) if i % 2 == 0]

  • 조건이 있는 구구단 n x m 으로 이루어진 구구단을 출력한다. 단, n은 짝수, m은 홀수여야 한다. n과 m은 1 이상 9 이하여야 한다.
    • 반복문 내 조건
        for n in range(1, 10):
            if n % 2 != 0:
                continue
            for m in range(1, 10):
                if m % 2 != 1:
                    continue
                print(f"{n} x {m} = {n*m}")
  • List Comprehension 으로 미리 범위 지정
        c1 = [x for x in range(1, 10) if x % 2 == 0]
        c2 = [x for x in range(1, 10) if x % 2 == 1]
        
        for n in c1:
            for m in c2:
                print(f"{n} x {m} = {n*m}")
  • 라인수를 줄인다면..
        for n in [x for x in range(1, 10) if x % 2 == 0]:
            for m in [x for x in range(1, 10) if x % 2 == 1]:
                print(f"{n} x {m} = {n*m}")

Dictionary 의 반복문

키:벨류 형태의 딕셔너리 변수도 for 문에서 사용이 가능한데

data = {
  "한국": "Republic of Korea",
  "중국": "China",
  "미국": "The United States of America",
}

for nation in data:
    print(nation)

>>> Output
한국
중국
미국

위처럼 nation 에 {”한국”: “Republic of Korea”} 이 오길 기대하지만, 키 항목만 오는걸 확인할 수 있는데,
이때 딕셔너리의 .items() 함수를 사용하면

for nation in data.items():
    print(nation)

>>> Output
('한국', 'Republic of Korea')
('중국', 'China')
('미국', 'The United States of America')

nation 변수에 튜플형식으로 (키, 벨류) 가 넘어오게 된다. nation[0], nation[1] 로도 접근이 가능하지만 각 키 벨류에 변수명을 할당할 수 있는데,

for korean, english in data.items():
    print(f"한국어: {korean} / 영어: {english}")

>>> Output
한국어: 한국 / 영어: Republic of Korea
한국어: 중국 / 영어: China
한국어: 미국 / 영어: The United States of America

키, 벨류순 으로 열거하여 각 변수에 할당해줄 수도 있다.

Tip!
키만 뽑아내는 data.keys(), 벨류만 뽑아내는 data.values() 도 활용할 수 있다.

리스트의 인덱스도 함께 알고 싶은데.. enumerate

input_str = "1,2,3,4,5"
for idx, val in enumerate(input_str.split(",")):
    print(f"{idx}번째 인덱스에 {val}이 있습니다.")

>>> Output
0번째 인덱스에 1이 있습니다.
1번째 인덱스에 2이 있습니다.
2번째 인덱스에 3이 있습니다.
3번째 인덱스에 4이 있습니다.
4번째 인덱스에 5이 있습니다.

이렇게 얻은 인덱스를 활용해 정수형으로 치환하기

input_str = "1,2,3,4,5".split(",")
for idx, val in enumerate(input_str):
    input_str[idx] = int(val)
print(input_str)

>>> Output
[1, 2, 3, 4, 5]

map 함수 이해하기

input_str = "1 2 3 4 5" 일때, 스페이스로 구분하여 각 원소를 정수화 하여 배열에 담기

# 1차원적인 방법으로
input_str = "1 2 3 4 5"
numbers = []
for n in input_str.split():
    numbers.append(int(n))
print(numbers)

>>> Output
[1, 2, 3, 4, 5]
input_str = "1 2 3 4 5"
numbers = list(map(int, input_str.split()))
print(numbers)

>>> Output
[1, 2, 3, 4, 5]  # 각 원소들이 정수형으로 변환되어 있다.

해설
1. input_str 변수를 .split() 하면 “ “ 를 기준으로 문자열을 잘라 리스트에 넣어준다.
input_str.split() → [”1”, “2”, “3”, “4”, “5”]
2. 리스트의 각 원소들을 int() 함수에 모두 대입해준다.
[int(”1”), int(”2”), ... int(”5”)]
⇒ [1, 2, 3, 4, 5]

  • 응용
    # 0 ~ 9 까지의 숫자 중 홀짝 구분하기
    def jjak(n):
        if n % 2 == 0:
            return f"{n}: 짝수"
    		else:
            return f"{n}: 홀수"
    
    # 더 간단하게 표현하면..
    def jjak(n):
        return f"{n}: 짝수" if n % 2 == 0 else f"{n}: 홀수"
    
    result = list(map(jjak, range(10)))
    print(result)
    
    >>> Output
    ['0: 짝수', '1: 홀수', '2: 짝수', '3: 홀수', ... '9: 홀수']

해설
return f"{n}: 짝수" if n % 2 == 0 else f"{n}: 홀수"
if n % 2 == 0 이면 f"{n}: 짝수", 아니면 f"{n}: 홀수"

  • 더 간단히(람다식.. 나중에..!!)
    result = list(map(lambda n: f"{n}: 짝수" if n % 2 == 0 else f"{n}: 홀수", range(10)))
    print(result)
    
    >>> Output
    ['0: 짝수', '1: 홀수', '2: 짝수', '3: 홀수', ... '9: 홀수']

0개의 댓글