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()vsappend()。 - 掌握 indentation 規則同
if / elif / else、=vs==、conditional expression (ternary operator)。 - 用
forloop 遍歷 list / tuple / dict (.items(),.keys(),.values())、range();用whileloop。 - Arithmetic operators (
//,%,**) 同 logical operators (and,or,not);orvs|嘅 precedence 陷阱。 - Built-in functions 同 custom functions:positional / keyword / default /
*argsarguments、return、variable scope。 - Recursion (binary search) 同 debugging 方法 (print, try-except, logging, debugger)。
- Lambda functions:語法、作為
sort(key=...)參數、作為 return value。 - Modules vs packages;
%pipvs!pip;install vs import。
⭐ 考試必溫 Top-5
- 讀 code 預測 output:
if/elif/else、for+range(start, stop, step)、while、dict looping。 - Function arguments:positional vs keyword vs default vs
*args(收集成 tuple);return 會即刻終止 function。 - Variable scope:function 入面改 immutable argument 唔影響外面。
- Lambda:
lambda arguments: expression;list.sort(key=lambda x: ...);my_func(5)(3)。 - 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
- 用
ifkeyword;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")
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
| Operator | Name | Description | Example | Result |
|---|---|---|---|---|
+ | Addition | 相加 | 5 + 3 | 8 |
- | Subtraction | 左減右 | 10 - 4 | 6 |
* | Multiplication | 相乘 | 3 * 4 | 12 |
/ | Division | 除法,永遠返回 decimal (float) | 10 / 2 | 5.0 |
// | Floor Division | 除完向下取整 | 11 // 3 | 3 |
% | Modulus | 只返回餘數 | 11 % 3 | 2 |
** | Exponentiation | 次方 | 2 ** 3 | 8 |
Logical operators 組合多個 conditions,返回 True/False:
and:兩個都 True 先 True —(5 > 3) and (2 < 4)→ Trueor:至少一個 True —(5 > 3) or (2 > 4)→ Truenot:反轉 —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
| 種類 | 寫法 | 說明 |
|---|---|---|
| Positional arguments | my_sum(1, 2) | 按定義次序對應:1 → a,2 → b |
| Keyword arguments | my_sum(b=1, a=7) | keyword=value,可以任意次序 |
| Default values | def my_sum(a=5, b=5) | call 時冇提供就用 default |
| Variable-length positional | def 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
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:用
loggingmodule 記錄訊息同事件。 - 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 一節。
由 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
| Install | Import | |
|---|---|---|
| 意思 | 下載並把外部 Python code 加到你部電腦 | 令 module / package 嘅 functions、classes、variables 喺當前 script / notebook 可用 |
| 點做 | terminal: pip install pandas;Jupyter: %pip install pandas | import 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
Lambda + key= 嘅思路 Week 4 會用喺 DataFrame.rename(mapper=lambda x: ...),之後亦會見到 Series.apply(lambda x: ...)。scikit-learn 嘅 imputers (Week 7) 同 COM6004 classification models 都靠呢度裝嘅 packages。Recursion + binary search 嘅「分而治之」概念亦係 COM6004 decision tree 遞歸分裂嘅基礎。
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)
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()returnNone— 睇 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。