1. while statement
i, total_sum = 10, 0 while i > 0: total_sum += i i -= 1 print("sum:", total_sum)
sum: 55
The
while statement is a control flow statement that has a condition before the :, and the code block following it is executed as long as the condition is met.2. if statement
2.1 if and else statements
score = int(input("Enter your score: ")) if score > 50: grade = "P" else: grade = "NP" print("grade:", grade)
Enter your score: 85 grade: P
The
if statement, similar to the while statement, has a condition before the :, and if the condition is met, the following code block is executed. If the condition is not met, the code block is not executed.And if an
else follows the if statement's code block, the code block after the else statement is executed when the if condition is not met.2.2 elif statement
score = int(input("Enter your score: ")) if score > 90: grade = "A" elif score > 80: grade = "B" elif score > 70: grade = "C" elif score > 60: grade = "D" else: grade = "F" print("grade:", grade)
Enter your score: 85 grade: B
If an
elif statement with a condition follows an if statement, and the if condition is not met but the elif condition is, the code block after the elif statement is executed.The
elif statement functions as if else and if are combined.An
elif or else statement can follow an elif statement, and this can continue with more elif statements.3. for statement
3.1 for statement iterating over a list
my_list = ["A", "B", "C"] for element in my_list: print(element)
A B C
The
for statement is a control flow statement that takes an iterable object and executes a block of code repeatedly for each item.An
iterable object is an object that can have multiple elements and their order, like a list.So, the
for statement has in in the middle, with the iterable object after in, and the variable name to be used for each element of the iterable object within the for code block before in.3.2 for statement iterating over a general iterable
my_dict = {"apple": "noun", "fly": "verb", "beautiful": "adjective"} for key, value in my_dict.items(): print(f"The part of speech for '{key}' is: {value}")
The part of speech for 'apple' is: noun The part of speech for 'fly' is: verb The part of speech for 'beautiful' is: adjective
The
iterable object that goes into a for statement is not limited to lists; any general iterable object can be used.In the case of the
dict.items method, it creates an iterable object by bundling the keys and values of the dict into tuples, so you can iterate over them with a for loop as in the example.4. range function
4.1 range(stop) function
for i in range(5): print(i)
0 1 2 3 4
The
range function is a function that returns an iterable object.When it receives one argument in the
range(stop) format, the range function returns an object that iterates from 0 up to (but not including) the given number.4.2 range(start, stop) and range(start, stop, step) functions
for i in range(1, 10): print("First range:", i) print() for i in range(1, 10, 5): print("Second range:", i)
First range: 1 First range: 2 First range: 3 First range: 4 First range: 5 First range: 6 First range: 7 First range: 8 First range: 9 Second range: 1 Second range: 6
A
range statement in the format range(start, stop) returns an object that iterates from start to stop.A
range statement in the format range(start, stop, step) is similar to the above format, but it returns an object that increments by the step value instead of 1.5. break and continue statements
for i in range(1, 10): if i == 5: break print("First for:", i) print() for i in range(1, 10): if i == 5: continue print("Second for:", i)
First for: 1 First for: 2 First for: 3 First for: 4 Second for: 1 Second for: 2 Second for: 3 Second for: 4 Second for: 6 Second for: 7 Second for: 8 Second for: 9
The
break statement can be used in loops like for or while, and if break is executed, it immediately terminates the loop and exits the code block.The
continue statement, similar to break, can be used in loops, and if continue is executed, it skips the current iteration and proceeds to the next one.These two control statements share the commonality of ending the current iteration, but they differ in whether they exit the loop's code block or not after being executed.
6. else clauses on loops and try statements
6.1 else clause on loops
for i in range(2, 10): for x in range(2, i): if i % x == 0: print(f"{i} = {x}×{i//x}") break else: print(f"{i} is a prime number.")
2 is a prime number. 3 is a prime number. 4 = 2×2 5 is a prime number. 6 = 2×3 7 is a prime number. 8 = 2×4 9 = 3×3
When an
else statement is used with a loop like for or while instead of an if statement, the code block of the else statement is executed when the loop finishes.If a
break statement is executed inside the loop, it exits not only the loop's code block but also the else statement's code block.To put it simply, a loop with an
else clause is treated as a single block, so when a break statement is encountered, it exits the entire large code block bound by the else, not just the code block immediately after the loop.6.2 else clause on try statements
try: # Code that might raise an error pass except Exception: # Code to execute when an error occurs pass else: # Code to execute when no error occurs pass
And if an
else statement is used with a try statement, the code block of the else statement is executed if no exception occurs in the try code block.Thus, the
else statement can be used for different purposes not only with if statements but also with loops and try statements.7. pass statement
if True: pass def function(): pass class MyClass: pass
# IndentationError if True: # IndentationError def function(): # IndentationError class MyClass:
The
pass statement does nothing in the code.In Python, indentation is required to distinguish code blocks in constructs like
if, def, and class. If an empty code block is left completely empty, an IndentationError will occur.Therefore, when developing, code blocks that are to be implemented later should not be left empty but should be filled with a
pass statement.8. match statement
8.1 match statement for matching values
def grade_calculator(letter_grade: str) -> float: match letter_grade[0]: case 'A': grade = 4.0 case 'B': grade = 3.0 case 'C': grade = 2.0 case 'D': grade = 1.0 case 'F': grade = 0.0 case _: raise ValueError("Invalid letter grade. Must be start with A, B, C, D, or F.") match letter_grade[1:]: case '+': grade += 0.3 case '-': grade -= 0.3 case '' | '0': pass case _: raise ValueError("Invalid modifier. Must be '+' or '-' or empty.") return grade print("A+ grade:", grade_calculator("A+")) print("B- grade:", grade_calculator("B-")) print("C0 grade:", grade_calculator("C0")) print("F grade:", grade_calculator("F"))
A+ grade: 4.3 B- grade: 2.7 C0 grade: 2.0 F grade: 0.0
The
match statement functions similarly to the switch-case statements in other languages and can also perform pattern matching.If the value of the variable following
match matches the value following case, the code block of that case is executed.If
| is used to connect cases, the code block is executed if either of the values matches.If one
case statement is matched, the code blocks of other case statements are ignored.The
case _: which will be explained next, is executed only if no other case statements are matched.8.2 match statement for matching patterns
def what_is(arg_x: int, arg_y: int): match (arg_x, arg_y): case (0, 0): print("Origin") case (0, y): print(f"Point on the y-axis: (0, {y})") case (x, 0): print(f"Point on the x-axis: ({x}, 0)") case (x, y) if x == y: print(f"Point on y = x: ({x}, {y})") case (asdf, qwer): print(f"A general point: ({asdf}, {qwer})") case _: raise ValueError("Unknown point") what_is(0, 0) what_is(0, 3) what_is(4, 4) what_is(2, 1)
Origin Point on the y-axis: (0, 3) Point on y = x: (4, 4) A general point: (2, 1)
The
match statement can match not only values but also general patterns.If a pattern including a variable name follows a
case statement, the code block is executed if the pattern matches, and the variable name can be used within that block.The pattern can be matched generally regardless of the variable name, and you can set it arbitrarily like
asdf, qwer and use it within the case block.The
case _: used in the previous example can match any value for a single variable with the variable name _, so it can be seen as matching when no previous case statement has matched.Here, the variable name
_ has a special conventional role of not using the matched variable inside the case's code block, but only using it as a matching pattern.Also, if you add
if after a case pattern, the case's code block is executed only if the pattern matches and the condition after if is satisfied.8.3 Class pattern matching
class Point: def __init__(self, x, y): self.x = x self.y = y def what_is(point: Point): match point: case Point(x = 0, y = 0): print("Origin") case Point(x = 2, y = y): print(f"Point with x-coordinate 2: (2, {y})") case Point(x = x, y = 3): print(f"Point with y-coordinate 3: ({x}, 3)") case Point() as p if p.y == 2 * p.x: print(f"Point on y = 2x: ({p.x}, {p.y})") case Point() as zxcv: print(f"A general point: ({zxcv.x}, {zxcv.y})") case _: raise ValueError("Unknown point") what_is(Point(0, 0)) what_is(Point(2, 3)) what_is(Point(3, 6)) what_is(Point(0, 4))
Origin Point with x-coordinate 2: (2, 3) Point on y = 2x: (3, 6) A general point: (0, 4)
When a class instance is used for pattern matching, you can match by entering the constructor's variable names as keyword arguments, like
x = 2, y = y.Also, if you add
as after a case pattern, you can reference and use the entire class instance being brought in, like p.class Point: __match_args__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y def what_is(point: Point): match point: case Point(0, 0): print("Origin") case Point(x, 0): print(f"Point on the x-axis: ({x}, 0)") case Point(0, y): print(f"Point on the y-axis: (0, {y})") case Point(x, y): print(f"A general point: ({x}, {y})") case _: raise ValueError("Unknown point") what_is(Point(0, 0)) what_is(Point(3, 0)) what_is(Point(0, 4)) what_is(Point(2, 3))
Origin Point on the x-axis: (3, 0) Point on the y-axis: (0, 4) A general point: (2, 3)
Also, by defining
__match_args__ in a class, you can specify the variables to be used for pattern matching.Defining
__match_args__ allows you to match patterns more conveniently than matching with keyword arguments.8.4 List & Dictionary pattern matching
def list_match(arg_list: list): match arg_list: case []: print("Empty list") case [x]: print(f"List with one element: [{x}]") case [x, y]: print(f"List with two elements: [{x}, {y}]") case [x, y, 0]: print(f"List with three elements ending in 0: [{x}, {y}, 0]") case [x, y, *rest]: print(f"List with three or more elements: [{x}, {y}, ...{rest}]") list_match([]) list_match([1]) list_match([2, 3]) list_match([4, 5, 0]) list_match([6, 7, 8, 9, 10])
Empty list List with one element: [1] List with two elements: [2, 3] List with three elements ending in 0: [4, 5, 0] List with three or more elements: [6, 7, ...[8, 9, 10]]
When matching a list with a pattern, you can create a pattern that unpacks the list.
In the example, by using
*rest as a pattern, you can match the pattern by unpacking the third and subsequent elements into rest.def dict_match(arg_dict: dict): match arg_dict: case {"a": x}: print(f"Dictionary with key 'a': {{'a': {x}}}") case {"b": y, "c": 0}: print(f"Dictionary with key 'b' and key 'c' with value 0: {{'b': {y}, 'c': {0}}}") case {"d": x, **rest}: print(f"Dictionary with key 'd' and other items: {{'d': {x}, ...{rest}}}") case {}: print("Empty dictionary") dict_match({}) dict_match({"a": 1}) dict_match({"b": 2, "c": 0}) dict_match({"d": 3, "e": 4, "f": 5})
Empty dictionary Dictionary with key 'a': {'a': 1} Dictionary with key 'b' and key 'c' with value 0: {'b': 2, 'c': 0} Dictionary with key 'd' and other items: {'d': 3, ...{'e': 4, 'f': 5}}
When matching a dictionary with a pattern, you can create a pattern with the values of the dictionary's keys.
Also, as in the example with
**rest, you can match the pattern by unpacking arbitrary elements into rest.