KR_While - somaz94/python-study GitHub Wiki

Python ๋ฐ˜๋ณต๋ฌธ(While) ๊ฐœ๋… ์ •๋ฆฌ


1๏ธโƒฃ while๋ฌธ์ด๋ž€?

while๋ฌธ์€ ์กฐ๊ฑด์ด ์ฐธ์ธ ๋™์•ˆ ์ฝ”๋“œ ๋ธ”๋ก์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ๋ฐ˜๋ณต๋ฌธ์ด๋‹ค. ์กฐ๊ฑด์ด ๊ฑฐ์ง“์ด ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰๋œ๋‹ค.

# ๊ธฐ๋ณธ while๋ฌธ ๊ตฌ์กฐ
while ์กฐ๊ฑด:
    ์ˆ˜ํ–‰ํ• _๋ฌธ์žฅ1
    ์ˆ˜ํ–‰ํ• _๋ฌธ์žฅ2
    ...

# ์˜ˆ์ œ: 1๋ถ€ํ„ฐ 5๊นŒ์ง€ ์ถœ๋ ฅ
number = 1
while number <= 5:
    print(number)
    number += 1

โœ… ์ฃผ์˜์‚ฌํ•ญ:

  • ๋ฌดํ•œ ๋ฃจํ”„ ์ฃผ์˜
  • ์กฐ๊ฑด๋ฌธ ํ•„์ˆ˜
  • ๋“ค์—ฌ์“ฐ๊ธฐ ํ•„์ˆ˜


2๏ธโƒฃ ๋ฐ˜๋ณต๋ฌธ ์ œ์–ด

# break: ๋ฐ˜๋ณต๋ฌธ ์ข…๋ฃŒ
coffee = 10
while True:
    if coffee == 0:
        print("์ปคํ”ผ๊ฐ€ ๋ชจ๋‘ ์†Œ์ง„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.")
        break
    print(f"๋‚จ์€ ์ปคํ”ผ: {coffee}์ž”")
    coffee -= 1

# continue: ํ˜„์žฌ ๋ฐ˜๋ณต์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค์Œ ๋ฐ˜๋ณต์œผ๋กœ
number = 0
while number < 10:
    number += 1
    if number % 2 == 0:
        continue    # ์ง์ˆ˜๋ฉด ์ถœ๋ ฅํ•˜์ง€ ์•Š์Œ
    print(number)  # ํ™€์ˆ˜๋งŒ ์ถœ๋ ฅ

โœ… ์ œ์–ด๋ฌธ:

  • break: ๋ฐ˜๋ณต๋ฌธ์„ ์™„์ „ํžˆ ์ข…๋ฃŒ
  • continue: ํ˜„์žฌ ๋ฐ˜๋ณต์„ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค์Œ ๋ฐ˜๋ณต์œผ๋กœ
  • ์กฐ๊ฑด๋ฌธ๊ณผ ํ•จ๊ป˜ ์ž์ฃผ ์‚ฌ์šฉ


3๏ธโƒฃ ๋ฌดํ•œ ๋ฃจํ”„

# ๋ฌดํ•œ ๋ฃจํ”„ ๊ธฐ๋ณธ ๊ตฌ์กฐ
while True:
    user_input = input("์ข…๋ฃŒํ•˜๋ ค๋ฉด 'q'๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”: ")
    if user_input == 'q':
        break
    print("์ž…๋ ฅ๊ฐ’:", user_input)

# ์‹ค์ œ ์‘์šฉ ์˜ˆ์ œ
def calculator():
    while True:
        command = input("๊ณ„์‚ฐํ•  ์‹์„ ์ž…๋ ฅํ•˜์„ธ์š” (์ข…๋ฃŒ: q): ")
        if command == 'q':
            break
        try:
            result = eval(command)
            print(f"๊ฒฐ๊ณผ: {result}")
        except:
            print("์˜ฌ๋ฐ”๋ฅธ ์ˆ˜์‹์„ ์ž…๋ ฅํ•˜์„ธ์š”")

โœ… ๋ฌดํ•œ ๋ฃจํ”„ ํŠน์ง•:

  • while True: ํ˜•ํƒœ๋กœ ์ž‘์„ฑ
  • ๋ฐ˜๋“œ์‹œ ์ข…๋ฃŒ ์กฐ๊ฑด ํ•„์š”
  • ์‹ค์ˆ˜๋กœ ๋งŒ๋“ค๋ฉด ํ”„๋กœ๊ทธ๋žจ ๊ฐ•์ œ ์ข…๋ฃŒ ํ•„์š”


4๏ธโƒฃ while๋ฌธ ํ™œ์šฉ ์˜ˆ์ œ

# ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ
def menu_system():
    while True:
        print("\n1. ํŒŒ์ผ ์—ด๊ธฐ")
        print("2. ํŒŒ์ผ ์ €์žฅ")
        print("3. ์ข…๋ฃŒ")
        choice = input("์„ ํƒํ•˜์„ธ์š”: ")
        
        if choice == '1':
            print("ํŒŒ์ผ์„ ์—ฝ๋‹ˆ๋‹ค.")
        elif choice == '2':
            print("ํŒŒ์ผ์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.")
        elif choice == '3':
            print("ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.")
            break
        else:
            print("์ž˜๋ชป๋œ ์„ ํƒ์ž…๋‹ˆ๋‹ค.")

# ์กฐ๊ฑด๋ถ€ ๋ฐ˜๋ณต
def countdown(n):
    while n > 0:
        print(n)
        n -= 1
    print("๋ฐœ์‚ฌ!")

โœ… ํ™œ์šฉ Tip:

  • ์‚ฌ์šฉ์ž ์ž…๋ ฅ ์ฒ˜๋ฆฌ
  • ๊ฒŒ์ž„ ๋ฃจํ”„ ๊ตฌํ˜„
  • ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ
  • ํŒŒ์ผ ์ฒ˜๋ฆฌ
  • ๋„คํŠธ์›Œํฌ ํ†ต์‹ 


5๏ธโƒฃ while๊ณผ else ๊ตฌ๋ฌธ

while๋ฌธ์—์„œ๋„ for๋ฌธ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ else ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. while ์กฐ๊ฑด์ด ๊ฑฐ์ง“์ด ๋˜์–ด ๋ฃจํ”„๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋  ๋•Œ else ๋ธ”๋ก์ด ์‹คํ–‰๋œ๋‹ค. break๋กœ ๋ฃจํ”„๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด else ๋ธ”๋ก์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

# ๊ธฐ๋ณธ ๊ตฌ์กฐ
while ์กฐ๊ฑด:
    # ์กฐ๊ฑด์ด ์ฐธ์ธ ๋™์•ˆ ์‹คํ–‰
    ์ˆ˜ํ–‰ํ• _๋ฌธ์žฅ
else:
    # ์กฐ๊ฑด์ด ๊ฑฐ์ง“์ด ๋˜์–ด ๋ฃจํ”„๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด ์‹คํ–‰
    ์ข…๋ฃŒ_ํ›„_์ˆ˜ํ–‰ํ• _๋ฌธ์žฅ

# ์†Œ์ˆ˜ ์ฐพ๊ธฐ ์˜ˆ์ œ
def is_prime(n):
    if n <= 1:
        return False
    
    i = 2
    while i * i <= n:
        if n % i == 0:
            print(f"{n}์€ {i}๋กœ ๋‚˜๋ˆ„์–ด๋–จ์–ด์ง‘๋‹ˆ๋‹ค.")
            break
        i += 1
    else:
        print(f"{n}์€ ์†Œ์ˆ˜์ž…๋‹ˆ๋‹ค.")
        return True
    
    return False

# ์‚ฌ์šฉ ์˜ˆ์‹œ
is_prime(17)  # ์ถœ๋ ฅ: 17์€ ์†Œ์ˆ˜์ž…๋‹ˆ๋‹ค.
is_prime(25)  # ์ถœ๋ ฅ: 25์€ 5๋กœ ๋‚˜๋ˆ„์–ด๋–จ์–ด์ง‘๋‹ˆ๋‹ค.

โœ… while-else ํŠน์ง•:

  • ๋ฃจํ”„๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ข…๋ฃŒ๋  ๋•Œ๋งŒ else ๋ธ”๋ก ์‹คํ–‰
  • break๋กœ ์ค‘๋‹จ๋˜๋ฉด else ๋ธ”๋ก ์‹คํ–‰๋˜์ง€ ์•Š์Œ
  • ๊ฒ€์ƒ‰, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๋“ฑ์— ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ
  • ์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ‘œํ˜„ ๊ฐ€๋Šฅ


6๏ธโƒฃ ์ค‘์ฒฉ ๋ฐ˜๋ณต๋ฌธ๊ณผ ์ œ์–ด ํ๋ฆ„

์ค‘์ฒฉ๋œ ๋ฐ˜๋ณต๋ฌธ์—์„œ์˜ ์ œ์–ด ํ๋ฆ„๊ณผ best practice์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค.

# ๊ธฐ๋ณธ ์ค‘์ฒฉ while๋ฌธ
i = 1
while i <= 5:
    j = 1
    while j <= i:
        print("*", end="")
        j += 1
    print()  # ์ค„๋ฐ”๊ฟˆ
    i += 1

# ์ค‘์ฒฉ ๋ฃจํ”„์—์„œ ํŠน์ • ๋ฃจํ”„๋งŒ ์ข…๋ฃŒํ•˜๊ธฐ
i = 1
while i <= 5:
    j = 1
    while j <= 5:
        print(f"({i}, {j})", end=" ")
        if j == 3:
            break  # ๋‚ด๋ถ€ ๋ฃจํ”„๋งŒ ์ข…๋ฃŒ
        j += 1
    print()
    i += 1

# ์ค‘์ฒฉ ๋ฃจํ”„์—์„œ ๋ชจ๋“  ๋ฃจํ”„ ์ข…๋ฃŒํ•˜๊ธฐ
found = False
i = 1
while i <= 5 and not found:
    j = 1
    while j <= 5:
        if i * j > 10:
            print(f"์ฒซ ๋ฒˆ์งธ 10๋ณด๋‹ค ํฐ ๊ณฑ: {i} * {j} = {i*j}")
            found = True
            break  # ๋‚ด๋ถ€ ๋ฃจํ”„ ์ข…๋ฃŒ
        j += 1
    i += 1

โœ… ์ค‘์ฒฉ ๋ฃจํ”„ ์ œ์–ด ๊ธฐ๋ฒ•:

  • ํ”Œ๋ž˜๊ทธ ๋ณ€์ˆ˜ ํ™œ์šฉ
  • ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ return ์‚ฌ์šฉ
  • ๊ฐ ๋ฃจํ”„์˜ ์—ญํ•  ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„
  • ๊ฐ€๋Šฅํ•˜๋ฉด ๊นŠ์€ ์ค‘์ฒฉ ํ”ผํ•˜๊ธฐ
  • ๋ฐ˜๋ณต๋ฌธ ์ถ”์ถœ ๋ฆฌํŒฉํ† ๋ง ๊ณ ๋ ค


7๏ธโƒฃ while๋ฌธ ์„ฑ๋Šฅ ์ตœ์ ํ™”

while๋ฌธ์„ ์‚ฌ์šฉํ•  ๋•Œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

import time

# ์ตœ์ ํ™” ์ „
def compute_factorial_unoptimized(n):
    result = 1
    while n > 0:
        result *= n
        n -= 1
    return result

# ์ตœ์ ํ™” 1: ์กฐ๊ฑด ๊ฒ€์‚ฌ ์ตœ์†Œํ™”
def compute_factorial_optimized1(n):
    result = 1
    while n > 1:  # n > 0 ๋Œ€์‹  n > 1 ์‚ฌ์šฉ (๋ถˆํ•„์š”ํ•œ ๊ณฑ์…ˆ ํšŒํ”ผ)
        result *= n
        n -= 1
    return result

# ์ตœ์ ํ™” 2: ์ง€์—ญ ๋ณ€์ˆ˜ ํ™œ์šฉ
def compute_factorial_optimized2(n):
    result = 1
    i = 2  # 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ  2๋ถ€ํ„ฐ ์‹œ์ž‘
    while i <= n:
        result *= i
        i += 1
    return result

# ์ตœ์ ํ™” 3: ๊ณ„์‚ฐ ์ค„์ด๊ธฐ
def compute_factorial_optimized3(n):
    if n <= 1:
        return 1
    
    result = 1
    i = n
    while i > 1:
        result *= i
        i -= 1
    return result

์กฐ๊ฑด ๊ฒ€์‚ฌ ์ตœ์ ํ™”

# ์ตœ์ ํ™” ์ „: ๋ฃจํ”„ ๋‚ด๋ถ€์—์„œ ์กฐ๊ฑด ๋งค๋ฒˆ ๊ณ„์‚ฐ
def find_in_sorted_list(sorted_list, target):
    i = 0
    while i < len(sorted_list):  # ๋งค๋ฒˆ len() ํ˜ธ์ถœ
        if sorted_list[i] == target:
            return i
        elif sorted_list[i] > target:  # ์ •๋ ฌ๋œ ๋ฆฌ์ŠคํŠธ์—์„œ ํƒ€๊ฒŸ๋ณด๋‹ค ํฐ ๊ฐ’์„ ๋งŒ๋‚˜๋ฉด ์ข…๋ฃŒ
            break
        i += 1
    return -1

# ์ตœ์ ํ™” ํ›„: ์กฐ๊ฑด์„ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐ
def find_in_sorted_list_optimized(sorted_list, target):
    i = 0
    length = len(sorted_list)  # ํ•œ ๋ฒˆ๋งŒ ๊ณ„์‚ฐ
    while i < length:
        value = sorted_list[i]  # ๋ฐ˜๋ณต์  ์ธ๋ฑ์‹ฑ ๋ฐฉ์ง€
        if value == target:
            return i
        elif value > target:
            break
        i += 1
    return -1

โœ… ์„ฑ๋Šฅ ์ตœ์ ํ™” ์›์น™:

  • ๋ฐ˜๋ณต์ ์ธ ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ”ผํ•˜๊ธฐ
  • ๋ฃจํ”„ ๋‚ด๋ถ€ ์—ฐ์‚ฐ ์ตœ์†Œํ™”
  • ๋ถˆํ•„์š”ํ•œ ์กฐ๊ฑด ๊ฒ€์‚ฌ ์ œ๊ฑฐ
  • ์ง€์—ญ ๋ณ€์ˆ˜ ํ™œ์šฉ์œผ๋กœ ์ฐธ์กฐ ์†๋„ ํ–ฅ์ƒ
  • ์ ์ ˆํ•œ ์ข…๋ฃŒ ์กฐ๊ฑด ์„ค์ •


8๏ธโƒฃ ๊ณ ๊ธ‰ while๋ฌธ ํŒจํ„ด

์‹ค์ œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ๊ณ ๊ธ‰ ํŒจํ„ด์ด๋‹ค.

1. ์ œํ•œ ์‹œ๊ฐ„/์‹œ๋„ ํŒจํ„ด

import time

def retry_operation(max_attempts=3, timeout=10):
    start_time = time.time()
    attempts = 0
    
    while attempts < max_attempts and (time.time() - start_time) < timeout:
        attempts += 1
        try:
            # ์‹คํ–‰ํ•  ์ž‘์—…
            print(f"์‹œ๋„ {attempts}...")
            if attempts == 2:  # ์„ฑ๊ณต ์‹œ๋ฎฌ๋ ˆ์ด์…˜
                print("์ž‘์—… ์„ฑ๊ณต!")
                return True
        except Exception as e:
            print(f"์˜ค๋ฅ˜ ๋ฐœ์ƒ: {e}")
            time.sleep(1)  # ์žฌ์‹œ๋„ ์ „ ๋Œ€๊ธฐ
    
    print("์ตœ๋Œ€ ์‹œ๋„ ํšŸ์ˆ˜ ์ดˆ๊ณผ ๋˜๋Š” ์‹œ๊ฐ„ ์ดˆ๊ณผ")
    return False

# ์‚ฌ์šฉ ์˜ˆ์‹œ
retry_operation()

2. ์ƒ์‚ฐ์ž/์†Œ๋น„์ž ํŒจํ„ด

import queue
import threading
import time
import random

# ๊ณต์œ  ํ
buffer = queue.Queue(maxsize=10)
RUNNING = True

def producer():
    """๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฒ„ํผ์— ์ถ”๊ฐ€"""
    count = 0
    while RUNNING:
        if not buffer.full():
            item = f"์•„์ดํ…œ-{count}"
            buffer.put(item)
            print(f"์ƒ์‚ฐ: {item}")
            count += 1
        time.sleep(random.uniform(0.1, 0.5))

def consumer():
    """๋ฒ„ํผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์ฒ˜๋ฆฌ"""
    while RUNNING:
        if not buffer.empty():
            item = buffer.get()
            print(f"์†Œ๋น„: {item}")
            buffer.task_done()
        time.sleep(random.uniform(0.2, 0.7))

# ์Šค๋ ˆ๋“œ ์‹œ์ž‘
producer_thread = threading.Thread(target=producer)
consumer_thread = threading.Thread(target=consumer)

producer_thread.start()
consumer_thread.start()

# 10์ดˆ ๋™์•ˆ ์‹คํ–‰ ํ›„ ์ข…๋ฃŒ
time.sleep(10)
RUNNING = False
producer_thread.join()
consumer_thread.join()

3. ํด๋ง(Polling) ํŒจํ„ด

def wait_for_resource(resource_check_fn, timeout=30, check_interval=1):
    """๋ฆฌ์†Œ์Šค๊ฐ€ ์ค€๋น„๋  ๋•Œ๊นŒ์ง€ ์ฃผ๊ธฐ์ ์œผ๋กœ ํ™•์ธ"""
    start_time = time.time()
    
    while (time.time() - start_time) < timeout:
        if resource_check_fn():
            print("๋ฆฌ์†Œ์Šค ์ค€๋น„ ์™„๋ฃŒ!")
            return True
        
        print("๋ฆฌ์†Œ์Šค ์ค€๋น„ ์ค‘...")
        time.sleep(check_interval)
    
    print("๋ฆฌ์†Œ์Šค ์ค€๋น„ ์‹œ๊ฐ„ ์ดˆ๊ณผ")
    return False

# ์‚ฌ์šฉ ์˜ˆ์‹œ
def is_database_ready():
    # ์‹ค์ œ๋กœ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ํ™•์ธ
    import random
    return random.random() > 0.7

wait_for_resource(is_database_ready)

โœ… ๊ณ ๊ธ‰ ํŒจํ„ด ์žฅ์ :

  • ์žฌ์‹œ๋„ ๋กœ์ง ํ‘œ์ค€ํ™”
  • ๋™์‹œ์„ฑ ์ฒ˜๋ฆฌ ํŒจํ„ด ์ œ๊ณต
  • ํƒ€์ž„์•„์›ƒ ๊ด€๋ฆฌ ์šฉ์ด
  • ๋น„๋™๊ธฐ ์ž‘์—… ์กฐ์œจ
  • ์—๋Ÿฌ ์ƒํ™ฉ ์šฐ์•„ํ•œ ์ฒ˜๋ฆฌ


9๏ธโƒฃ while๋ฌธ๊ณผ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ

while๋ฌธ๊ณผ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

# ๊ธฐ๋ณธ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ
def fibonacci_generator(limit):
    a, b = 0, 1
    count = 0
    
    while count < limit:
        yield a
        a, b = b, a + b
        count += 1

# ์‚ฌ์šฉ ์˜ˆ์‹œ
for num in fibonacci_generator(10):
    print(num)  # 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

# ๋ฌดํ•œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ
def infinite_counter(start=0, step=1):
    """๋ฌดํ•œํžˆ ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ"""
    n = start
    while True:
        yield n
        n += step

# ํ•„์š”ํ•œ ๋งŒํผ๋งŒ ์†Œ๋น„
for i, num in enumerate(infinite_counter(10, 5)):
    print(num)
    if i >= 5:  # ์ฒ˜์Œ 6๊ฐœ ๊ฐ’๋งŒ ๊ฐ€์ ธ์˜ด
        break

# ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹
def evens_under(n):
    """n ๋ฏธ๋งŒ์˜ ์ง์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ‘œํ˜„์‹"""
    return (i for i in range(n) if i % 2 == 0)

# ์ง€์—ฐ ํ‰๊ฐ€(Lazy Evaluation) ํ™œ์šฉ
def search_in_large_file(file_path, search_term):
    """๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์—์„œ ํŠน์ • ๋‹จ์–ด๊ฐ€ ํฌํ•จ๋œ ์ค„ ์ฐพ๊ธฐ"""
    with open(file_path, 'r') as file:
        line_number = 0
        while True:
            line = file.readline()
            if not line:  # ํŒŒ์ผ ๋
                break
            
            line_number += 1
            if search_term in line:
                yield (line_number, line.strip())

โœ… ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ์žฅ์ :

  • ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ (ํ•„์š”ํ•  ๋•Œ๋งŒ ๊ฐ’ ์ƒ์„ฑ)
  • ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ๋ฌดํ•œ ์‹œํ€€์Šค ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ
  • ์ง€์—ฐ ํ‰๊ฐ€๋กœ ์„ฑ๋Šฅ ํ–ฅ์ƒ
  • I/O ๋ฐ”์šด๋“œ ์ž‘์—…์˜ ํšจ์œจ ํ–ฅ์ƒ


๐Ÿ”Ÿ ๋น„๋™๊ธฐ while๋ฌธ๊ณผ ๋™์‹œ์„ฑ

๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ while๋ฌธ์„ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

import asyncio

# ๋น„๋™๊ธฐ while ๋ฃจํ”„
async def async_counter(limit):
    count = 0
    while count < limit:
        print(f"์นด์šดํŠธ: {count}")
        await asyncio.sleep(0.5)  # ๋น„์ฐจ๋‹จ ๋Œ€๊ธฐ
        count += 1
    return count

# ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
async def event_processor(queue, timeout=None):
    start_time = asyncio.get_event_loop().time()
    
    while timeout is None or (asyncio.get_event_loop().time() - start_time) < timeout:
        try:
            # 0.1์ดˆ ๋™์•ˆ ํ์—์„œ ํ•ญ๋ชฉ ๋Œ€๊ธฐ
            event = await asyncio.wait_for(queue.get(), 0.1)
            print(f"์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ: {event}")
            queue.task_done()
        except asyncio.TimeoutError:
            print("์ด๋ฒคํŠธ ๋Œ€๊ธฐ ์ค‘...")
            # ํ๊ฐ€ ๋น„์–ด์žˆ์–ด๋„ ๋ฃจํ”„ ๊ณ„์† ์‹คํ–‰
            continue

# ๋น„๋™๊ธฐ ์ž‘์—… ๋™์‹œ ์‹คํ–‰
async def concurrent_tasks():
    # ์ด๋ฒคํŠธ ํ ์ƒ์„ฑ
    event_queue = asyncio.Queue()
    
    # ์ด๋ฒคํŠธ ์ƒ์„ฑ์ž ํ•จ์ˆ˜
    async def event_generator():
        for i in range(10):
            event = f"์ด๋ฒคํŠธ-{i}"
            await event_queue.put(event)
            print(f"์ด๋ฒคํŠธ ์ƒ์„ฑ: {event}")
            await asyncio.sleep(0.7)
    
    # ๋‘ ์ž‘์—… ๋™์‹œ ์‹คํ–‰
    await asyncio.gather(
        event_generator(),
        event_processor(event_queue, timeout=10)
    )

# ๋น„๋™๊ธฐ ํƒ€์ž„์•„์›ƒ ํŒจํ„ด
async def with_timeout(coroutine, timeout=5.0):
    try:
        return await asyncio.wait_for(coroutine, timeout)
    except asyncio.TimeoutError:
        print("์ž‘์—… ์‹œ๊ฐ„ ์ดˆ๊ณผ")
        return None

# ์‚ฌ์šฉ ์˜ˆ์‹œ
async def main():
    # ์นด์šดํ„ฐ ์‹คํ–‰
    await with_timeout(async_counter(10), 3.0)
    
    # ๋™์‹œ ์ž‘์—… ์‹คํ–‰
    await concurrent_tasks()

# ๋น„๋™๊ธฐ ๋ฉ”์ธ ํ•จ์ˆ˜ ์‹คํ–‰
asyncio.run(main())

โœ… ๋น„๋™๊ธฐ while๋ฌธ ํŠน์ง•:

  • asyncio.sleep()๋กœ ๋น„์ฐจ๋‹จ ๋Œ€๊ธฐ
  • ๋‹ค๋ฅธ ์ฝ”๋ฃจํ‹ด์˜ ์‹คํ–‰์„ ํ—ˆ์šฉ
  • ๋น„๋™๊ธฐ ํ๋ฅผ ํ™œ์šฉํ•œ ํ†ต์‹ 
  • ํƒ€์ž„์•„์›ƒ ํŒจํ„ด ์ง€์›
  • ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๊ฐ€๋Šฅ


1๏ธโƒฃ1๏ธโƒฃ ์‹ค์ „ ์‘์šฉ: ์ƒํƒœ ๊ธฐ๊ณ„ ๊ตฌํ˜„

while๋ฌธ์„ ํ™œ์šฉํ•œ ์ƒํƒœ ๊ธฐ๊ณ„(State Machine) ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์ด๋‹ค.

class StateMachine:
    def __init__(self, initial_state):
        self.state = initial_state
        self.handlers = {}
        self.end_states = []
    
    def add_state(self, name, handler, end_state=False):
        """์ƒํƒœ ์ถ”๊ฐ€"""
        self.handlers[name] = handler
        if end_state:
            self.end_states.append(name)
    
    def run(self, cargo):
        """์ƒํƒœ ๊ธฐ๊ณ„ ์‹คํ–‰"""
        while self.state not in self.end_states:
            # ํ˜„์žฌ ์ƒํƒœ์— ๋Œ€ํ•œ ํ•ธ๋“ค๋Ÿฌ ๊ฐ€์ ธ์˜ค๊ธฐ
            handler = self.handlers[self.state]
            # ํ•ธ๋“ค๋Ÿฌ ์‹คํ–‰ ๋ฐ ๋‹ค์Œ ์ƒํƒœ์™€ ํ™”๋ฌผ ๋ฐ›๊ธฐ
            self.state, cargo = handler(cargo)
        
        return cargo

# ์˜ˆ์ œ: ํ…์ŠคํŠธ ์ฒ˜๋ฆฌ ์ƒํƒœ ๊ธฐ๊ณ„
def start_state(text):
    """์‹œ์ž‘ ์ƒํƒœ: ํ…์ŠคํŠธ ์ค€๋น„"""
    words = text.split()
    return 'process_words', words

def process_words(words):
    """๋‹จ์–ด ์ฒ˜๋ฆฌ ์ƒํƒœ"""
    if not words:
        return 'end', []
    
    processed_words = [word.strip('.,!?').lower() for word in words]
    return 'count_length', processed_words

def count_length(words):
    """๊ธธ์ด ๊ณ„์‚ฐ ์ƒํƒœ"""
    word_lengths = [(word, len(word)) for word in words]
    return 'end', word_lengths

# ์ƒํƒœ ๊ธฐ๊ณ„ ์ƒ์„ฑ ๋ฐ ์‹คํ–‰
def process_text(text):
    sm = StateMachine('start')
    sm.add_state('start', start_state)
    sm.add_state('process_words', process_words)
    sm.add_state('count_length', count_length)
    sm.add_state('end', None, end_state=True)
    
    result = sm.run(text)
    return result

# ์‚ฌ์šฉ ์˜ˆ์‹œ
text = "Python์€ ๊ฐ„๊ฒฐํ•˜๊ณ  ์ฝ๊ธฐ ์‰ฌ์šด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์ž…๋‹ˆ๋‹ค!"
word_lengths = process_text(text)
for word, length in word_lengths:
    print(f"'{word}': {length}์ž")

โœ… ์ƒํƒœ ๊ธฐ๊ณ„ ์žฅ์ :

  • ๋ณต์žกํ•œ ํ๋ฆ„์„ ๋ช…ํ™•ํžˆ ํ‘œํ˜„
  • ์ƒํƒœ ์ „ํ™˜ ๋กœ์ง ๋ถ„๋ฆฌ
  • ์ฝ”๋“œ ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ
  • ํ™•์žฅ์„ฑ์ด ๋†’์€ ๊ตฌ์กฐ
  • ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ


1๏ธโƒฃ2๏ธโƒฃ ๋””๋ฒ„๊น…๊ณผ ๋ฌธ์ œ ํ•ด๊ฒฐ

while๋ฌธ ์‚ฌ์šฉ ์‹œ ํ”ํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•๊ณผ ๋””๋ฒ„๊น… ํ…Œํฌ๋‹‰์ด๋‹ค.

์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋“ค

  1. ๋ฌดํ•œ ๋ฃจํ”„
# ๋ฌธ์ œ: ์ข…๋ฃŒ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜์ง€ ์•Š์Œ
i = 10
while i > 0:
    print(i)
    # i -= 1  # ์ฃผ์„ ํ•ด์ œ๋กœ ํ•ด๊ฒฐ

# ํ•ด๊ฒฐ: ํƒ€์ž„์•„์›ƒ ํŒจํ„ด ์ ์šฉ
def with_timeout(func, args=(), timeout=5):
    import threading
    import time
    
    result = [None]
    exception = [None]
    
    def worker():
        try:
            result[0] = func(*args)
        except Exception as e:
            exception[0] = e
    
    thread = threading.Thread(target=worker)
    thread.daemon = True
    thread.start()
    thread.join(timeout)
    
    if thread.is_alive():
        raise TimeoutError(f"ํ•จ์ˆ˜ ์‹คํ–‰์ด {timeout}์ดˆ๋ฅผ ์ดˆ๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค.")
    
    if exception[0]:
        raise exception[0]
    
    return result[0]
  1. ์ž˜๋ชป๋œ ์กฐ๊ฑด
# ๋ฌธ์ œ: ์กฐ๊ฑด ํ‰๊ฐ€ ์˜ค๋ฅ˜
data = [1, 2, 3]
i = 0
while i < len(data):
    print(data[i])
    data.append(i)  # ๋งค ๋ฐ˜๋ณต๋งˆ๋‹ค ๋ฆฌ์ŠคํŠธ ํฌ๊ธฐ๊ฐ€ ์ฆ๊ฐ€ํ•ด ๋ฌดํ•œ ๋ฃจํ”„ ๋ฐœ์ƒ
    i += 1

# ํ•ด๊ฒฐ: ๋ณ„๋„ ๋ณ€์ˆ˜์— ๊ธธ์ด ์ €์žฅ
data = [1, 2, 3]
i = 0
length = len(data)  # ์ฒ˜์Œ ๊ธธ์ด๋งŒ ์‚ฌ์šฉ
while i < length:
    print(data[i])
    data.append(i)  # ๋ฃจํ”„ ์กฐ๊ฑด์— ์˜ํ–ฅ ์—†์Œ
    i += 1
  1. ์˜คํ”„๋ฐ”์ด์›(Off-by-one) ์˜ค๋ฅ˜
# ๋ฌธ์ œ: ํ•œ ๋ฒˆ ๋” ๋ฐ˜๋ณตํ•˜๊ฑฐ๋‚˜ ํ•œ ๋ฒˆ ๋œ ๋ฐ˜๋ณต
arr = [10, 20, 30, 40, 50]
i = 0
while i <= len(arr):  # ์ž˜๋ชป๋œ ์กฐ๊ฑด (<=)
    # ์ธ๋ฑ์Šค ์˜ค๋ฅ˜ ๋ฐœ์ƒ
    print(arr[i])
    i += 1

# ํ•ด๊ฒฐ: ์ •ํ™•ํ•œ ์กฐ๊ฑด ์‚ฌ์šฉ
i = 0
while i < len(arr):  # ์˜ฌ๋ฐ”๋ฅธ ์กฐ๊ฑด (<)
    print(arr[i])
    i += 1

๋””๋ฒ„๊น… ๊ธฐ๋ฒ•

# ๋กœ๊น… ์ถ”๊ฐ€
import logging
logging.basicConfig(level=logging.DEBUG)

def process_with_logging(data):
    i = 0
    while i < len(data):
        logging.debug(f"์ธ๋ฑ์Šค: {i}, ๊ฐ’: {data[i]}")
        # ์ฒ˜๋ฆฌ ๋กœ์ง
        i += 1

# ์ƒํƒœ ์Šค๋ƒ…์ƒท
def process_with_snapshot(data, max_iterations=1000):
    i = 0
    iterations = 0
    
    while i < len(data) and iterations < max_iterations:
        # ์ฃผ๊ธฐ์ ์œผ๋กœ ์ƒํƒœ ์ถœ๋ ฅ
        if iterations % 100 == 0:
            print(f"์ง„ํ–‰ ์ƒํ™ฉ: {i}/{len(data)}")
        
        # ์ฒ˜๋ฆฌ ๋กœ์ง
        i += 1
        iterations += 1
    
    if iterations >= max_iterations:
        print("์ตœ๋Œ€ ๋ฐ˜๋ณต ํšŸ์ˆ˜ ์ดˆ๊ณผ")

โœ… ๋””๋ฒ„๊น… ํŒ:

  • ์ค‘๊ฐ„ ๊ฐ’ ์ถœ๋ ฅ
  • ๋ฐ˜๋ณต ํšŸ์ˆ˜ ์ œํ•œ
  • ์žฌํ˜„ ๊ฐ€๋Šฅํ•œ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค ์ž‘์„ฑ
  • ๋กœ๊น… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉ
  • ๊ฐ€์ • ๊ฒ€์ฆํ•˜๊ธฐ
  • ๋” ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆ„๊ธฐ


โš ๏ธ **GitHub.com Fallback** โš ๏ธ