Back-End/Python

[Python] 2. Python의 제어 흐름 도구(for, range(), if, pass, match, else, break continue)

Tinkies 2025. 2. 12. 22:52

1. if 문

파이썬의 if문은 자바스크립트 언어와 비슷한 형식으로 사용합니다.

x = int(input("Please enter an integer: "))
# Please enter an interger: 1

if(x < 0):
     x = 0
     print("Negative changed to zero")
elif x == 0:
    print("Zero")
elif x == 1:
    print("Single") # More
else:
    print('More')

 

숫자가 없거나 여러 개의 elif 문이 있고 else는 그 안에 원하는 숫자가 없을 경우 입니다. elif는 else if를 줄인 표현식으로 과도한 드령쓰기 방지에 유용합니다. 

 

2.for문

파이썬에서 for문은 C언어나 파스칼에서 사용하는 방식과 약간 다릅니다. 

sports = ['football', 'baseball', 'cricket'];

for w in sports:
     print(w, len(w))

''' football 8
baseball 8
cricket 7
'''

 

컬렉션을 이터레이트 하는 동안 같은 컬렉션을 수정하는 코드는 올바르게 동작하기 힘들고, 대신 보통 컬렉션의 복사본으로 루프를 만들거나 새 컬렉션을 만드는 것이 간단합니다.

# Create a users collection
users = {'Koke': 'active', 'Rike': 'inactive', 'Ko':'active'}

# Strategy: Iterate over a copy
for user, status in users.copy().items():
      if status == 'inactive':
           del users[user]

# Strategy: Create a new collection
active_users = {}
for user, status in users.items():
     if status == 'active':
         active_users[user] = status

 

3.range() 함수

숫자들의 시퀀스 이터레이트할 필요가 있다면 내장 함수 range()가 편합니다.

for i in range(5):
     print(i)

# 0
# 1
# 2
# 3
# 4

 

끝값은 만들어지는 수열에 포함되지 않고, range(10)은 약 10개의 값을 만드는데, 길이 10인 시퀀스의 항목을 가리키는 올바른 인덱스들입니다. 범위가 다른 숫자로 시작하거나, 다른 증가분을(음수 가능) 지정하는 것도 가능합니다.

a = list(range(5,10))
print(a)
# [5,6,7,8,9]

b = list(range(0, 10, 3))
print(b)
# [0, 3, 6, 9]

c = list(range(-5, -60, -20))
print(c)
# [-5, -25, -45]

 

시퀀스의 인덱스들로 이터레이트를 하려면 range()len()을 결합할 수 있습니다.

d = ['Mary', 'had', 'a', 'little', 'lamb']
for i in range(len(d)):
    print(i, d[i])
'''
0 Mary
1 had
2 a
3 little
4 lamb
'''

 

하지만 대부분 enumerate() 함수를 쓰는 것이 더 편리합니다. 범위를 그냥 인쇄하면 다음과 같습니다.

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

 

range()가 돌려준 객체는 리스트인 것처럼 동작하나, 사실 리스트가 아닙니다 이터레이트 시 원하는 시퀀스 항목들을 순서대로 돌려주는 객체지만, 실제로 리스트를 만들지 않아서 공간을 절약합니다. 이런 객체를 이터러블 이라 부릅니다. 

 

공급이 소진될 때까지 일련의 항목들을 얻을 수  있는 무엇인가를 기대하는 함수는 구조물들의 타깃으로 적합합니다. for문이 그런 구조물이고, 이터러블을 취하는 함수의 예로 sum()이 있습니다.

print(sum(range(4))) # 0 + 1 + 2 + 3 = 6
print(sum(range(5))) # 1 + 2 + 3 + 4 = 10
print(sum(range(6))) # 1 + 2 + 3 + 4 + 5 = 15
print(sum(range(7))) # 1 + 2 + 3 + 4 + 5 + 6 = 21

 

4. break 와 continue 

break는 가장 안쪽에있는 for문 또는 while문을 벗어납니다.

for n in range(2, 10):
    for x in range(2, n):
          if n % x == 0:
              print(f"{n} equals {x} * {n//x}")
'''
4 equals 2 * 2
6 equals 2 * 3
6 equals 3 * 2
8 equals 2 * 4
8 equals 4 * 2
9 equals 3 * 3
'''

 

continue는 루프의 다음 반복을 계속합니다

for num in range(2, 10):
      if num % 2 == 0:
        print(f"Found an even number {num}")
        continue
        print(f"Found an odd number {num}")
        
'''
Found an even number 2
Found an even number 4
Found an even number 6
Found an even number 8
'''

 

5.else Clauses on Loops

for문 또는 while 루프에 break 문은 다른 절과 쌍을 이룰 수 있습니다. loop가 break를 실행하지 않고 완료하면 다른 절이 실행됩니다. for loop에서 다른 절은 루프가 최종 반복을 완료한 후, 즉 중단이 발생하지 않을 경우 실행됩니다. 그 후 루프의 조건이 false가 된 후 실행됩니다.

 

어떤 종류의 루프에서도 루프가 중단으로 종료된 경우 else 절이 실행되지 않습니다. 물론 반환 또는 예외 상향 조정과 같이 루프를 조기에 종료하는 다른 방법도 else 절에 실행을 건너뛸 수 있습니다. 

for n in range(2, 10):
     for x in range(2, n):
          if n % x == 0:
              print(n, 'equals', x, '*', n//x)
              break
     else:
           # loop 실패시
           print(n, 'is a prime number')
           
'''
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
'''

 

루프가 실행되면 if / if/ if / else 와 같은 시퀀스가 실행됩니다. if 가 루프 내부에 있으면 여러 번 발생했고, 조건이 참이라면 중단이 발생합니다. 조건이 참이 아닐 시 루프 외부의 다른 절이 실행됩니다. 루프를 함께 사용할 때, else 절은 if 문보다 try 문의 else 절과 더 많은 공통점을 같습니다.

 

try문의 else 절은 예외가 발생하지 않을 때 실행되고, 루프의 else 절은 중단이 발생하지 않을 때 실행됩니다. 

 

6. pass 문 

pass 문은 아무것도 하지 않습니다. 문법적으로 문장이 필요하나, 프로그램이 특별히 할 일이 없을 때 사용할 수 있습니다.

while True:
     pass # 키보든 대기 중 (Ctrl + C)

 

클래스를 만들 때도 흔히 사용됩니다.

class MyEmptyClass:
    pass

 

pass가 사용될 수 있는 다른 환경은 새 코드를 작업할 때 함수나 조건부 바디의 자리를 채우는 것이며, pass는 조용히 무시됩니다.

def initlog(*args):
     pass # Remember to implement this!

 

7.match 문

match 문은 하나 이상의 케이스 블록으로 주어진 연속적 패턴과 그 값을 비교합니다. 이는 표면적으로 C, Java 또는 JavaScript(및 기타 언어들)의 switch 문과 유사하나 Rust나 Haskell과 같은 언어의 패턴 매칭과 더욱 유사합니다. 일치하는 첫 번째 패턴만 실행되며 값에서 구성 요소(시퀀스 요소 또는 객체 속성)를 변수로 추출할 수 있습니다.

def http_error(status):
    match status:
          case 400:
              return "Bad request!"
          case 404:
              return "404 Not Found"
          case 418:
              return "teapot"
          case _:
              return "Something's wrong with the internet"

 

마지막 블록은 와일드카드 역할을 하며 절대 일치하지 않거나 일치하는 경우가 없으면 분기가 실행되지 않습니다. | ("또는")을 사용하 여러 리터럴을 하나의 패턴으로 결합할 수 있습니다.

def http_error(status):
    match status:
          case 400 | 403 | 404:
              return "Not allowed"
          case _:
              return "Something's wrong with the internet"

 

패턴은 할당을 푸는 것처럼 보일 수 있고 변수를 바인딩하는 데 사용할 수 있습니다.

match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, y={y}")
    case _:
        raise ValueError("Not Point")

 

첫번째 패턴에는 두 개의 리터럴이 있으며 위에 표시된 리터럴 패턴의 확장으로 생각할 수 있으나 다음 두 패턴은 리터럴과 변수를 결합하고 변수는 피사체(점)의 값을 바인딩 합니다. 네 번째 패턴은 두 개의 값을 캡처하므로 언패킹 할당(x,y) = 점과 개념적으로 유사합니다.

 

클래스를 사용해 데이터를 구조화하는 경우 클래스 이름 뒤에 생성자와 유사한 인수 목록을 사용할 수 있지만 속성을 변수로 캡처할 수 있습니다.

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def where_is(point):
    match point:
        case Point(x=0, y=0):
            print("Origin")
        case Point(x=0, y=y):
            print(f"Y={y}")
        case Point(x=x, y=0):
            print(f"X={x}")
        case Point():
            print("Somewhere else")
        case _:
            print("Not a Point")

 

일부 내장 클래스에서 속성(데이터 클래스)에 대한 순서를 제공하는 위치 매개변수를 사용할 수 있습니다. 클래스에는 __match_args__ 특수 속성을 설정하여 패턴의 속성에 대한 특정 위치를 정의할 수 있습니다. ("x", "y")로 설정된 경우 다음 패턴은 모두 동등하며 모두 y 속성을 var 변수에 바인딩 합니다.

Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)

 

패턴을 읽는 방법을 권장하는 것은 할당의 왼쪽에 놓을 변수의 확장된 형태로 보고, 어떤 변수가 무엇에 설정될지 이해하는 것입니다. match 문에는 독립형 이름(var과 같은)만 할당됩니다.  점선 이름(foo, bar), 속성 이름(위 x, y) 또는 클래스 이름은 할당되지 않습니다.

 

패턴은 임의로 중첩될 수 있습니다. 예를 들어 포인트 목록에 __match_args__가 추가된 경우 다음과 같이 매칭할 수 있습니다.

class Point:
     __match_args__ = ('x', 'y')
     def __init__(self, x, y):
         self.x = x
         self.y = y

match points:
    case []:
        print("No points")
    case [Point(0, 0)]:
        print("The Origin")
    case [Point(x, y)]:
        print(f"Single point {x}, {y}")
    case [Point(0, y1), Point(0, y2)]:
        print(f"Two on the Y alxis at {y1}, {y2}")
    case _ :
        print("Something else")

 

패턴에 if 절을 추가할 수 있는데, 이를 "gaurd(가드)"라고 합니다. 가드가 거짓인 경우 매치는 다음 케이스 블록을 시도합니다. 가드가 평가하기 전 값 캡쳐가 발생합니다.

match point:
    case Point(x, y) if x == y:
      print(f"Y=X at {x}")
    case Point(x, y):
        print(f"Not on the diagonal")

 

  • 튜플 패턴과 리스트 패턴은 정확히 동일한 의미를 가지며 실제로 임의의 시퀀스와 일치합니다. 중요한 예외는 반복자나 문자열과 일치하지 않다는 것
  • 시퀀스 패턴은 확장 언팩을 지원합니다. [x, y, *rest] 및 (x,y, *휴식)은 할당을 언팩하는 것과 유사하게 작동합니다. * 뒤에 오는 이름도 _일 수 있으므로 (x,y *_)는 나머지 항목을 바인딩하지 않고 최소 두 항목의 시퀀스와 일치합니다.
  • 매핑 패턴: {"bandwidth": b, "latency": I}은 사전에 "대역폭"과 "지연" 값을 캡쳐합니다. 시퀀스 패턴과 달리 추가 키는 무시됩니다. **rest와 같은 언패킹도 지원됩니다. (하지만 **_는 중복되므로 허용되지 않습니다.)
  • 하위 패턴은 키워드로 캡쳐할 수 있습니다.
case (Point(x1, y1), Point(x2, y2) as p2): ...

 

입력의 두 번째 요소로 p2로 캡쳐합니다 (입력이 두 점의 시퀀스인 경우)

  • 대부분 리터럴은 평등으로 비교되지만, 싱글톤인 True, False, None은 정체성으로 비교됩니다
  • 패턴은 명명된 상수를 사용할 수 있습니다. 패턴이 캡처 변수로 해석되지 않도록 하려면 점선 이름이어야 합니다.
from enum import Enum
class Color(Enum):
    RED = 'red'
    GREEN = 'green'
    BLUE = 'blue'

color = Color(input("Enter your choice of 'red', 'blue' or 'green': "))

match color:
    case Color.RED:
        print("I see red!")
    case Color.GREEN:
        print("Grass is green")
    case Color_BLUE:
        print("I'm feeling the blues :(")

참고 자료

 

4. More Control Flow Tools

As well as the while statement just introduced, Python uses a few more that we will encounter in this chapter. if Statements: Perhaps the most well-known statement type is the if statement. For exa...

docs.python.org

 

 

GitHub - Koras02/python-blog

Contribute to Koras02/python-blog development by creating an account on GitHub.

github.com

 

LIST