All Revision Notes

COM6001 Computing with Big Data · Week 3

Python Basics II: Control Statements, Functions, Lambda & Packages

COM6001 · Week 3 · Source: Lecture03_Python_crash_course.pdf (exported Jupyter notebook, 28 pages) · Lab 3 Q1–Q8

Contents · 9 sections

🎯 本講重點 (Learning outcomes)

  • 理解 return value (Week 2 Q7 回顧):pop() vs append()。
  • 掌握 indentation 規則同 if / elif / else、= vs ==、conditional expression (ternary operator)。
  • 用 for loop 遍歷 list / tuple / dict (.items(), .keys(), .values())、range();用 while loop。
  • Arithmetic operators (//, %, **) 同 logical operators (and, or, not);or vs | 嘅 precedence 陷阱。
  • Built-in functions 同 custom functions:positional / keyword / default / *args arguments、return、variable scope。
  • Recursion (binary search) 同 debugging 方法 (print, try-except, logging, debugger)。
  • Lambda functions:語法、作為 sort(key=...) 參數、作為 return value。
  • Modules vs packages;%pip vs !pip;install vs import。

⭐ 考試必溫 Top-5

  1. 讀 code 預測 output:if/elif/else、for + range(start, stop, step)、while、dict looping。
  2. Function arguments:positional vs keyword vs default vs *args (收集成 tuple);return 會即刻終止 function。
  3. Variable scope:function 入面改 immutable argument 唔影響外面。
  4. Lambda:lambda arguments: expression;list.sort(key=lambda x: ...);my_func(5)(3)。
  5. Install (每個 environment 一次) vs Import (每個 session 都要);%pip 優於 !pip。

1. Review: return values (Week 2 Q7)

本講係一份 Jupyter notebook。開頭先講 Week 3 起嘅交功課方法:用 cell-level copy and paste 將題目相關嘅 cells 抄去新 notebook,以姓名 + student ID 命名,交 PDF 去 Moodle;唔好交成份有晒教學內容嘅原 notebook。

然後回顧 Week 2 Q7:

my_list = [1, 2, 3]
print(my_list.pop(0))      # 1
print(my_list.append(0))   # None

help(my_list.append)
# append(object, /) method of builtins.list instance
#     Append object to the end of the list.
help(my_list.pop)
# pop(index=-1, /) method of builtins.list instance
#     Remove and return item at index (default last).
#     Raises IndexError if list is empty or index is out of range.
my_list.pop.__doc__        # 直接攞 docstring 字串
⭐ 考試重點

睇 docstring:pop 寫 “Remove and return item”,所以 print() 印到被移除嘅值;append 只係 append,冇 return → 印出 None。另外 pop(index=-1, /) 表示 index default 係 -1 (最後一個);list 空或 index out of range 會 raise IndexError。

2. Control statements: indentation & if

2.0 Groups of statements — indentation matters!

Python 用 colon (冒號) : 開始一組 statements,組內所有 statements 要用相同 indentation (縮進距離)。Python 冇規定一定要幾多個 spaces,但建議 4 spaces (PEP 8)。

🖼️ 圖片內容

indentation.png 同 if_syntax.png (notebook 第 2 頁) 係圖片,文字擷取不到;請對照原 PDF 第 2 頁。

2.1 if statement

  • 用 if keyword;if 入面嘅 statements 要 indent 並且 indentation 一致,condition 為 True 時先執行。
  • Condition 可以係 assertions (==, >, <…) 或者 function 返回嘅 Boolean value。
  • 多過一個 condition 用 elif。
weather = 'Sunny'
print(f"The weather is {weather}.")
if weather == 'Sunny':
    print("Don't forget your suncream!")
elif weather == 'rainy':
    print("Dont forget your umbrella!")
else:
    print("Have a nice day!")
# The weather is Sunny.
# Don't forget your suncream!
⭐ = vs ==

weather = 'sunny' → assignment (將值 assign 畀 variable)。
weather == 'sunny' → assertion (比較,返回 True / False)。if weather = 'sunny': 會出 SyntaxError。

Indentation problems (Lab Q1)

# Example 1 (錯):if 後面一定要有 indented 嘅 action
if weather == 'sunny':
print('let"s go to the beach')        # IndentationError: expected an indented block

# 修正
if weather == 'sunny':
    print("let's go to the beach")    # 用雙引號包住,入面先可以用 apostrophe '

# Example 2 (錯):同一 block 嘅 indentation 唔一致 / else 對錯位
# 修正
if weather == 'sunny':
    print("let's go to the beach")
    print('we will be happy')
else:
    print("let's stay at home")
💡 修正 apostrophe (撇號)

Slide 用 'let"s go' 迴避問題。正確英文要 Let's:外面用雙引號 "let's go",或者用 escape 'let\'s go'。

elif vs else

  • elif 要有 condition — 「if something occurs」。
  • else 冇 condition — 「for all other cases」。else: 之後唔可以再有 branch,否則 SyntaxError: invalid syntax。
if weather == 'sunny':
    print('beach')
else:
    print('home')
elif weather == 'rainy':      # ✗ SyntaxError:else 一定係最後一個 branch
    print('home')

Lab Q2 參考答案

for i in [-5, 0, 3, 8]:
    if i < 0:
        print('Negative')
    elif i == 0:
        print('Equal to zero')
    elif i < 5:                 # 去到呢度已知 i > 0
        print('Positive but smaller than 5')
    else:
        print('Positive and larger than or equal to 5')
# Negative / Equal to zero / Positive but smaller than 5 / Positive and larger than or equal to 5

Conditional expression (ternary operator)

一行寫簡單 if-else:value_if_true if condition else value_if_false。適合根據 condition assign 值,可以用喺 assignments、function arguments、list comprehensions 等。Tip:只用於簡單 condition,保持可讀性。

weather = 'sunny'
result = "Let's go to the beach" if weather == 'sunny' else "Let's stay at home"
print(result)     # Let's go to the beach

3. Loops: for, range, while

3.1 for loops

for loop 用嚟 iterate 一個 iterable object 嘅元素;list、tuple、甚至 dict 都係 iterable。

for item in object:
    statement(s)
l1 = [1, 2, 3, 4, 5]
for i in l1:
    print(i)          # 1 2 3 4 5 (每行一個)

Supplementary: Arithmetic & Logical operators

OperatorNameDescriptionExampleResult
+Addition相加5 + 38
-Subtraction左減右10 - 46
*Multiplication相乘3 * 412
/Division除法,永遠返回 decimal (float)10 / 25.0
//Floor Division除完向下取整11 // 33
%Modulus只返回餘數11 % 32
**Exponentiation次方2 ** 38

Logical operators 組合多個 conditions,返回 True/False:

  • and:兩個都 True 先 True — (5 > 3) and (2 < 4) → True
  • or:至少一個 True — (5 > 3) or (2 > 4) → True
  • not:反轉 — not(5 > 3) → False

Example: odd / even (list 或 tuple 都得)

l1 = (1, 2, 3, 4, 5)     # tuple 同 list 一樣可以 loop
for i in l1:
    if i % 2 == 0:
        print(f"{i} is even")
    else:
        print(f"{i} is odd")
# 1 is odd / 2 is even / 3 is odd / 4 is even / 5 is odd

3.2 Looping over dictionaries

Dict 係 iterable,可以 loop 佢嘅 keys、values 或 items。Python 3.7 起 dict 保留 insertion order;之前版本係 unordered (可以 loop,但次序冇保證)。Notebook 用嘅係 Python 3.10。

d1 = {"name": "aileen", "marks": 100}
type(d1.items())    # dict_items
type(d1.keys())     # dict_keys
type(d1.values())   # dict_values

for pair in d1:            print(pair)   # name / marks          ← 直接 loop dict 得到 key
for pair in d1.items():    print(pair)   # ('name','aileen') / ('marks',100)  ← tuple(key, value)
for pair in d1.keys():     print(pair)   # name / marks
for pair in d1.values():   print(pair)   # aileen / 100

for d in d1.items():
    print(f"the 'key' is {d[0]} and its value is {d[1]}")
# the 'key' is name and its value is aileen
# the 'key' is marks and its value is 100
⭐ 考試重點

直接 loop dict 只會得到 keys;要同時攞 key 同 value 就 loop dict.items(),每個元素係一個 (key, value) tuple (可以 for k, v in d1.items(): unpack)。

3.3 range()

range 係 built-in function,產生一串數字,常用嚟 loop 指定次數:range(stop)、range(start, stop)、range(start, stop, step)。同 slicing 一樣 stop 唔包含。產生嘅 sequence 係 iterable 但唔係 list (要 list(range(...)) 先變 list);直接 print 只會見到 range(1, 10)。

print(range(1, 10, 1))        # range(1, 10)  ← 唔會印出數字
for ii in range(1, 10, 1):
    print(ii)                 # 1 … 9 (冇 10)
for i in range(2, 10, 3):
    print(i)                  # 2 5 8

sum = 0                       # (slide 用 sum 做名;實際應避免覆蓋 built-in sum())
for i in range(13, 174, 7):
    sum += i
print(sum)    # 2070
print(i)      # 167 ← loop 完 i 保留最後一個值 (13 + 7×22 = 167;174 唔包含)

3.4 while loops

Condition 為 True 就一直 loop。要自己 increment / decrement iterator,否則 loop 永遠唔會停 (infinite loop)。

num = 0
while (num < 10):
    num += 1          # 忘記呢句 → while loop never ends
    print(num)        # 1 … 10

# 緊接住再行:
while (num in range(0, 10)):   # 此時 num == 10,唔喺 range(0,10) 入面 → 一次都唔行
    num = num + 1
print(num)            # 10
⚠️ 易錯位

第一個 while 印 1 至 10 (唔係 0 至 9):因為先 += 1 再 print;最後一輪 num = 9 < 10 成立 → 變 10 → 印 10。第二個 while 因為 num 已經係 10,condition False,所以 body 唔執行,只印 10。

Lab Q3: sum multiples of 3 or 5 (0 – 99999)

⭐ or vs | 嘅 precedence
a = 3
print((a%3==0) | (a%2==0))   # True  ← 有括號,先比較再 bitwise OR
print(a%3==0 | a%2==0)       # False ← | 優先過 ==,變成 a%3 == (0 | a%2) == 0 → 0 == 1 == 0 → False
print(a%3==0 or a%2==0)      # True  ← 建議用 or (precedence 低過 ==)
# for loop
total = 0
for i in range(0, 100000):          # 0 至 99999 (inclusive)
    if i % 3 == 0 or i % 5 == 0:
        total += i
print(total)    # 2333316668

# while loop
total, i = 0, 0
while i <= 99999:
    if i % 3 == 0 or i % 5 == 0:
        total += i
    i += 1                          # 自己 increment
print(total)    # 2333316668

4. Functions (and Methods)

Functions (同 methods) 係完成特定任務嘅 self-contained code modules:通常「take in」data、處理、「return」結果 (return 係 optional)。寫好之後可以重複使用,亦可以喺其他 functions 入面 call。Methods 係屬於特定 class 嘅 light functions,要先有該 class 嘅 object,再用 obj.abc()。

4.1 Built-in functions

Python interpreter 內置、永遠可用:print(), min(), max(), len(), type() 等 (完整列表:docs.python.org/3/library/functions.html)。

len("hello")     # 5
len([1, 2, 3])   # 3
len(1)           # TypeError: object of type 'int' has no len()

4.2 Custom-defined functions

點解唔 copy-paste 同一段 code? Copy-paste 較易出錯;要改嘅時候要去每一個位置改。定義 function 就只需改定義嗰一處,之後 call 名就得,code 更乾淨清晰。

Syntax:

  • 用 keyword def
  • 圓括號放 argument(s);可以係 variable length def func(*var)
  • 用 colon :
  • Function body 用相同 indentation
  • 可以有或冇 return value
🖼️ 圖片內容

Customized_Function.png (function 結構標注圖,notebook 第 10 頁) 係圖片,文字擷取不到;請對照原 PDF 該頁。

def calculate_area(width, height=3, *vars):
    """Calculate rectangle area from width and height."""   # docstring
    area = width * height
    if len(vars) > 0:
        for each in vars:
            print(each)
    return area

calculate_area(3, 5, ['random', 'input', 0])   # 印 ['random', 'input', 0];return 15
calculate_area(1)                              # height 用 default 3 → return 3

def my_sum(a, b):
    print(f'{a} + {b} is {a+b}')
    return a + b

my_sum(1, 2)              # 1 + 2 is 3
my_sum('Aileen', 'Hou')   # Aileen + Hou is AileenHou  ← + 對 str 係連接
my_sum(b=5, a=7)          # 7 + 5 is 12 ;Out: 12 (notebook 只顯示最後一句嘅 return)

def myFunc():             # 冇乜意義但語法正確
    return True
⭐ 考試重點:Input arguments & return
種類寫法說明
Positional argumentsmy_sum(1, 2)按定義次序對應:1 → a,2 → b
Keyword argumentsmy_sum(b=1, a=7)keyword=value,可以任意次序
Default valuesdef my_sum(a=5, b=5)call 時冇提供就用 default
Variable-length positionaldef f(*args)接受任意數量 positional args,收集成一個 tuple

Return:用 return statement;一執行到 explicit return,function 即刻終止,並把值送返 caller。

def my_sum(a=5, b=5):
    return a - b
    print("Execution completed.")   # 永遠唔會執行 (return 之後)

my_sum(1, 2)       # -1  positional:a=1, b=2
my_sum(b=1, a=7)   # 6   keyword
my_sum()           # 0   default 5 - 5

def print_arguments(*args):
    print(args)            # ('A', 'B', 'C') ← tuple
    for arg in args:
        print(arg)
print_arguments("A", "B", "C")

Variable scope

將 variable (例如 a) 傳入 function 時,對於 immutable types (例如 int),function 收到嘅效果等同一個 copy;function 入面改 a 唔會影響外面嘅 a。

a = 3
def my_update(a):
    a = a + 1
    print(f'inside the fucntion a is {a}')
my_update(a)
print(f'outside the function a is {a}')
# inside the fucntion a is 4
# outside the function a is 3
⚠️ 補充 (超出 slide 但常見)

Function 入面嘅 a 係 local variable。如果傳入嘅係 mutable object (例如 list) 而 function 用 .append() 修改佢,外面就會見到改變 — 因為兩個名指向同一個 object (Week 2 references 概念)。Slide 只講 immutable 情況。

Lab Q4 & Q5 參考答案

# Q4 (for loop)
def small_positive_number(seq):
    result = []
    for x in seq:
        if (x > 0) and (x < 5):
            result.append(x)
    return result                      # return,唔係 print

# Q4 (while loop)
def small_positive_number(seq):
    result, i = [], 0
    while i < len(seq):
        if 0 < seq[i] < 5:
            result.append(seq[i])
        i += 1
    return result

small_positive_number([1, 2, 0, 4, 6, 5, 2, 1])   # [1, 2, 4, 2, 1]

# Q5
def my_func_varargs(arg1, *vartuple):
    print(arg1)
    for v in vartuple:
        print(v)
    return 1 + len(vartuple)           # 總 argument 數量

my_func_varargs(1, 'a', 'b', 'c')      # 印 1 a b c;return 4

5. Recursion & Debugging

5.1 Recursion

Recursion:function call 自己,用嚟解決可以拆成較細、相似 subproblems 嘅問題。

  • 一定要有 base case,防止 infinite recursion,令 recursive calls 最終終止。
  • 某些問題用 recursion 更優雅易明,但對大 input 可能用更多 memory、更慢 (相比 iterative)。

例子:binary search — 喺已排序 list 搵 target:睇中間 mid,等於就 return;細過 target 就去右半邊搵;大過就去左半邊搵。

def binary_search(nums, target, left=None, right=None):
    if left is None:
        left = 0
    if right is None:
        right = len(nums) - 1
    if left >= right:            # ← base case (有 bug!)
        return -1
    mid = left + (right - left) // 2
    if nums[mid] == target:
        return mid
    elif nums[mid] < target:
        return binary_search(nums, target, mid + 1, right)
    else:
        return binary_search(nums, target, left, mid - 1)

my_list = [1, 2, 3, 4, 5]
binary_search(my_list, 3)   # 2 ✓
binary_search(my_list, 5)   # -1 ✗ 應該係 4

5.2 Debugging

Debugging = 找出並修正 errors / bugs。Python 常用工具:

  • Print statements:喺不同位置 print variables 嘅值。
  • Exception handling:try-except 捕捉 exceptions,幫助定位錯誤來源。
  • Logging:用 logging module 記錄訊息同事件。
  • Debuggers:IDE / command-line debugger,set breakpoints、逐步執行、inspect variables。
# 5.2.1 用 print debug
def binary_search(nums, target, left=None, right=None):
    if left is None: left = 0
    if right is None: right = len(nums) - 1
    print(f"left = {left}, right = {right} -> {nums[left:right + 1]}")
    if left >= right:
        print("break because left >= right")
        return -1
    mid = left + (right - left) // 2
    if nums[mid] == target:
        return mid
    elif nums[mid] < target:
        return binary_search(nums, target, mid + 1, right)
    else:
        return binary_search(nums, target, left, mid - 1)

binary_search(my_list, target=5)
# left = 0, right = 4 -> [1, 2, 3, 4, 5]
# left = 3, right = 4 -> [4, 5]
# left = 4, right = 4 -> [5]
# break because left >= right
# Out: -1

# 用 logging (效果一樣,但可以按 level 開關,唔使刪 print)
import logging
logging.basicConfig(level=logging.DEBUG)
# 將上面 print(...) 改成 logging.debug(...) → 輸出 DEBUG:root:left = 0, right = 4 -> ...

Debugger (IDE):set breakpoint (例如喺計 left / right 嗰行),暫停時檢查 left, right, mid, nums[mid]:

Button作用
Continue一直行直到撞到下一個 breakpoint
Step over執行當前一行,去下一行,唔會入去 function call 裡面
Step into如果當前行有 function call,入去該 function 第一行暫停
Step out行完當前 function,返去 caller,喺 call 之後嗰行暫停
🖼️ 圖片內容

Debugger.png (IDE debugger UI 截圖) 係圖片,文字擷取不到;請對照原 PDF debugging 一節。

⭐ 考試重點:Bug 解釋

由 print 可見最後一次 call 時 left == right == 4,nums[4] 正正係 5,但 condition left >= right 令 function 提早 return -1。修正:改為 if left > right: (只有 left 嚴格大過 right,即搜尋範圍為空,先 return -1)。修正後 binary_search(my_list, target=5) → 4。

Trace (修正版,target = 5):left=0,right=4,mid=2,nums[2]=3 < 5 → left=3;left=3,right=4,mid=3,nums[3]=4 < 5 → left=4;left=4,right=4,mid=4,nums[4]=5 ✓ return 4。

6. Anonymous (lambda) functions

先分清:statements 包括 expressions;expressions 一定會產生一個值。例:x = 1 係 statement (assignment),x == 1 係 expression (產生 True/False)。

Lambda function:細小、anonymous (冇名) 嘅 function,可以有多個 parameters 但只有一個 expression,又叫 lambda expression。

lambda arguments: expression
(lambda x, y: x - y)(3, 5)     # -2   ← 直接喺後面加 (args) call
sum_up = lambda x, y: x + y    # sum_up 只係成個 lambda body 嘅 "nickname"
sum_up(35, 5)                  # 40
(lambda x, y: x + y)(35, 5)    # 40   冇 nickname 都可以,用 () 包住 body

def remove_1st(x):             # 等價 full function
    return x[1:]
remove_1st_lambda = lambda x: x[1:]
remove_1st([1, 2, 3, 4, 5])          # [2, 3, 4, 5]
remove_1st_lambda(" Lecture 03")     # 'Lecture 03'  ← 對 string 一樣 work (slicing)

Lab Q6

is_even = lambda n: n % 2 == 0
print(is_even(4))   # True
print(is_even(7))   # False

Embedded usage: lambda 作為另一個 function 嘅 input

老師唔建議單獨用 lambda;佢主要用喺另一個 function 入面 — 作為 input parameter 或 return value。最經典:list.sort(key=...)。

id_string = ['a3', 'b1', 'c5', 'd2']
id_string.sort()                       # ['a3', 'b1', 'c5', 'd2']  按成個 string (第一個字母) 排
id_string.sort(key=lambda x: x[1])     # ['b1', 'd2', 'a3', 'c5']  按第二個字元 (數字) 排
💡 直覺理解

key 係一個「將每個元素轉成排序依據」嘅 function。sort 會對每個元素 call key(x),然後按結果排。lambda x: x[1] 即係「用第二個字元做排序依據」。

Lab Q7 參考答案

student_dict = {"b003": "John", "a005": "Robin", "a002": "Aileen", "b001": "Mary"}

def student_sort(d):
    key_list = list(d.keys())
    key_list.sort(key=lambda x: int(x[-3:]), reverse=True)   # 按數字部分 (最後 3 位) 降序
    sorted_values = []
    for k in key_list:                 # ['a005', 'b003', 'a002', 'b001']
        sorted_values.append(d[k])
    return sorted_values

student_sort(student_dict)   # ['Robin', 'John', 'Aileen', 'Mary']
⚠️ 留意

題目字面寫「descending by student number within each class」,但 hint 同 expected output 其實係唔理 class、單純按數字降序。int(x[-3:]) 將 '005' 轉做 5 再比較;如果唔轉 int 用 string 比較,呢個例子結果一樣,但 '10' vs '9' 呢類情況就會錯。另外 slide 用 dict 做 parameter 名會覆蓋 built-in,建議改 d。

Lambda 作為 function 嘅 return value

def my_func(adder):
    return lambda x: x + adder

my_func(5)        # <function my_func.<locals>.<lambda>(x)>  ← 返回嘅係一個 function
my_func(5)(3)     # 8   等於 (lambda x: x + 5)(3)
⭐ 考試重點

my_func(5) 返回 lambda x: x + 5 呢個 function 本身 (未執行),所以要再加一對括號提供 x:my_func(5)(3) → 8。

🖼️ 留意

Notebook 中 my_func(5)(3) 嘅輸出多咗一行 “mul is 5”,但顯示嘅 function 定義冇對應 print,相信係老師舊版 cell 殘留;以 function 定義為準,結果係 8。

7. Python packages & modules

  • Module:單一 .py 檔,包含 functions、classes、variables,可以 import 使用。
  • Package:有結構嘅 modules 集合,將相關 modules 組合埋一齊。
  • 用 import 載入:import math、import pandas as pd。
  • Python standard library 已包含好多 modules;numpy、pandas 等要另外安裝。
  • 用 modules / packages 組織 code 令程式更 readable、reusable、maintainable。

7.1 pip commands

pip 係 Python 嘅 package installer,用嚟 install、update、manage packages。可以喺 terminal / command prompt 用,或者喺 Jupyter 用 ! (執行 terminal command) — 但更建議用 %pip,因為佢保證裝喺 notebook 當前使用嘅 environment;!pip install 可能裝咗去另一個 environment。

Command作用
%pip show package_name檢查有冇裝、睇 version 同 location
%pip install package_name安裝
%pip uninstall package_name移除

7.2 Install vs Import

⭐ 考試重點
InstallImport
意思下載並把外部 Python code 加到你部電腦令 module / package 嘅 functions、classes、variables 喺當前 script / notebook 可用
點做terminal: pip install pandas;Jupyter: %pip install pandasimport pandas as pd
頻率每個 environment 一次每次開新 Python session / script 都要

口訣:Install before import.

Lab Q8

檢查並安裝:pandas (tables / DataFrames 嘅 data analysis & manipulation)、numpy (fast numerical operations、arrays)、seaborn (基於 matplotlib 嘅 statistical visualization)、plotly (interactive plotting)、scikit-learn (machine learning / data mining)。

%pip show pandas          # 每個 package 一個 cell
%pip show numpy
%pip show seaborn
%pip show plotly
%pip show scikit-learn    # 注意:install 名係 scikit-learn,import 名係 sklearn

import pandas as pd
import numpy as np
import seaborn as sns
import plotly.express as px
import sklearn

How to submit:將題目同答案放去另一個 notebook → export html → print as PDF → 確保所有 code、文字、outputs 都顯示 → 交 Moodle。

自我測驗 Self-test

Q1. 以下 code 輸出咩?for i in range(1, 12, 4): print(i)

1、5、9 (12 唔包含;下一個 13 已超出)。

Q2. d = {"a": 1, "b": 2}。for x in d: print(x) 同 for x in d.items(): print(x) 分別印咩?

第一個印 keys:a、b。第二個印 tuples:('a', 1)、('b', 2)。

Q3. 計算:17 // 5、17 % 5、2 ** 4、9 / 3

3、2、16、3.0 (/ 永遠返回 float)。

Q4. def f(a, b=2, *args): return a + b + len(args)。f(1)、f(1, 5)、f(1, 5, 'x', 'y')、f(b=1, a=3) 各返回咩?

f(1) = 1+2+0 = 3;f(1, 5) = 1+5+0 = 6;f(1, 5, 'x', 'y') = 1+5+2 = 8 (args = ('x','y') tuple);f(b=1, a=3) = 3+1+0 = 4。

Q5. 以下會印咩?點解?
x = 10
def g(x):
    x = x * 2
    return x
y = g(x)
print(x, y)

印 10 20。Function 入面嘅 x 係 local variable,改佢唔影響外面嘅 x (int 係 immutable);return 值 20 assign 畀 y。

Q6. 原本 binary_search 用 if left >= right: return -1,喺 [1,2,3,4,5] 搵 5 點解錯?點改?

最後一次 call left = right = 4,範圍只剩 [5],本應檢查 nums[4],但 left >= right 成立直接 return -1。改為 if left > right:,只有範圍真正為空先 return -1。修正後返回 4。

Q7. 寫一句 code 將 words = ['banana', 'kiwi', 'apple'] 按字串長度排序。

words.sort(key=lambda w: len(w)) (或 key=len) → ['kiwi', 'apple', 'banana']。

Q8. def h(n): return lambda x: x * n。h(3) 同 h(3)(4) 係咩?

h(3) 返回一個 function (lambda x: x * 3);h(3)(4) = 12。

Q9. Install 同 import 有咩分別?點解喺 Jupyter 用 %pip 而唔用 !pip?

Install = 下載 package 到電腦,每個 environment 做一次;import = 載入當前 session,每次新 session 都要做。%pip 保證裝喺 notebook 當前 kernel 嘅 environment;!pip 係行 shell command,可能裝咗去另一個 environment。

Q10. a = 3; print(a%3==0 | a%2==0) 點解係 False?

| (bitwise OR) 嘅 precedence 高過 ==,所以變成 a%3 == (0 | a%2) == 0 → 0 == 1 == 0 (chained comparison) → False。應該用括號或者用 or。

一頁總結 Cheat sheet

⭐ 考前速記
  • pop() remove & return;append() return None — 睇 docstring 有冇 “return”。
  • Block = colon : + 一致 indentation (建議 4 spaces);if 後一定要有 indented action。
  • = assignment vs == assertion;elif 有 condition,else 冇且必須最後。
  • Ternary:a if cond else b。
  • for item in iterable;dict 直接 loop = keys;.items() = (key, value) tuples;Python 3.7+ dict 保留 insertion order。
  • range(start, stop, step) stop 唔包含,唔係 list;while 要自己 increment。
  • / → float,// floor,% 餘數,** 次方;用 and/or/not,小心 | precedence。
  • def f(pos, kw=default, *args):;*args → tuple;return 即終止;immutable argument 喺 function 內改唔影響外面。
  • Recursion 要 base case;binary search bug:left >= right → 改 left > right。
  • Debug:print / try-except / logging / debugger (Continue, Step over, Step into, Step out)。
  • lambda args: expression;主要用作 sort(key=lambda x: ...) 或 return value;my_func(5)(3)。
  • Module = 一個 .py;package = modules 集合。%pip show/install/uninstall;Install 一次 / Import 每 session;install before import。