Chọn đến phần học sinh cần nhanh chóng thông qua mục lục bằng cách click đến phần đó
- I. Lý thuyết trọng tâm
- 1. Biến cục bộ – Biến khai báo bên trong hàm
- 2. Biến toàn cục – Biến khai báo bên ngoài hàm
- 3. Từ khoá global – Cho phép hàm thay đổi biến toàn cục
- II. Hướng dẫn thực hành
- Nhiệm vụ 1: Lọc phần tử từ danh sách
- Nhiệm vụ 2: Tách từ và chuyển đổi kiểu chữ
- Nhiệm vụ 3: Chương trình phân loại số nguyên bằng nhiều hàm
- III. Phương pháp giải các dạng bài tập
- Dạng 1: Viết hàm trích xuất và xử lý dữ liệu từ danh sách
- Dạng 2: Viết hàm trả về nhiều giá trị kết hợp thuật toán
- Dạng 3: Viết chương trình kiểm tra tính hợp lệ của dữ liệu
- IV. Sơ đồ tư duy
I. Lý thuyết trọng tâm
1. Biến cục bộ – Biến khai báo bên trong hàm
Khi một biến được tạo ra bên trong thân hàm, nó chỉ “sống” trong phạm vi hàm đó. Bên ngoài hàm, biến này không tồn tại và nếu cố truy cập sẽ gặp lỗi NameError.
Điều này áp dụng cho cả tham số của hàm: khi truyền giá trị vào hàm, Python tạo ra bản sao cục bộ. Mọi phép gán lại bên trong hàm chỉ tác động lên bản sao, không ảnh hưởng biến gốc bên ngoài.
Ví dụ minh hoạ:
>>> def func(a, b):
n = 10
a = a * 2
b = a + b
return a + b + n
>>> a = 1
>>> b = 2
>>> func(a, b)
16
>>> a, b
(1, 2)
>>> n
NameError: name 'n' is not defined
Phân tích:
- Bên trong
func, các biếnn,a,blà biến cục bộ. Dùavàbtrùng tên với biến bên ngoài, chúng hoàn toàn độc lập. - Sau khi hàm kết thúc,
avẫn là1,bvẫn là2– không bị thay đổi. - Gọi
nở ngoài hàm → lỗi, vìnchỉ tồn tại trongfunc.
💡 Ghi nhớ: Trong Python, tất cả biến khai báo trong hàm đều mang tính địa phương (cục bộ), không có hiệu lực bên ngoài hàm.
Câu hỏi vận dụng lý thuyết:
Cho đoạn lệnh:
>>> a, b = 1, 2
>>> def f(a, b):
a = a + b
b = b * a
return a + b
Giá trị của a, b bên ngoài hàm sau khi gọi f(1, 2) hoặc f(10, 20)?
Đáp án: Dù gọi f(1, 2) hay f(10, 20), giá trị a, b bên ngoài luôn là 1, 2 vì a, b trong hàm f là biến cục bộ.
Có thể khai báo biến trong hàm trùng tên với biến ngoài hàm không?
Đáp án: Có thể. Hai biến trùng tên nhưng nằm ở phạm vi khác nhau thì hoàn toàn độc lập, không ảnh hưởng lẫn nhau.
2. Biến toàn cục – Biến khai báo bên ngoài hàm
Biến được tạo ở chương trình chính (ngoài mọi hàm) có phạm vi rộng hơn. Tuy nhiên, cách hàm tương tác với biến này có hai tình huống khác nhau:
Tình huống 1: Hàm có thể ĐỌC giá trị biến toàn cục
Nếu bên trong hàm chỉ sử dụng giá trị của biến (không gán lại), Python cho phép truy cập bình thường.
>>> def f(a, b):
return a + b + N
>>> N = 10
>>> f(1, 2)
13
Hàm f truy cập được giá trị N = 10 dù N khai báo bên ngoài.
Tình huống 2: Hàm KHÔNG THỂ thay đổi biến toàn cục (mặc định)
Nếu bên trong hàm có phép gán cho biến trùng tên với biến ngoài, Python tự động coi đó là biến cục bộ mới – biến ngoài không bị ảnh hưởng.
>>> def f(n):
t = n + 1
return t
>>> t = 10
>>> f(5)
6
>>> t
10
Dù hàm f gán t = n + 1 = 6, biến t ngoài hàm vẫn giữ nguyên giá trị 10.
3. Từ khoá global – Cho phép hàm thay đổi biến toàn cục
Khi cần hàm thực sự thay đổi giá trị của biến ngoài hàm, ta khai báo biến đó với từ khoá global ngay bên trong hàm.
Cú pháp:
def tên_hàm():
global tên_biến
# thao tác với biến
Ví dụ:
>>> def f(n):
global t
t = 2 * n + 1
return t
>>> t = 10
>>> f(1)
3
>>> t
3
Sau khi gọi f(1), biến t ở chương trình chính đã thay đổi từ 10 thành 3.
💡 Nguyên tắc: Biến ngoài hàm chỉ có thể đọc bên trong hàm. Muốn ghi/thay đổi thì phải dùng
global.
Câu hỏi vận dụng lý thuyết:
Cho hàm:
>>> def f(x, y):
a = 2 * (x + y)
print(a + n)
Kết quả in ra khi thực hiện:
n = 10
f(1, 2)
Đáp án:
- $a = 2 \times (1 + 2) = 6$
- Hàm truy cập biến
n = 10từ bên ngoài - Kết quả in ra: $6 + 10 = \textbf{16}$
II. Hướng dẫn thực hành
Nhiệm vụ 1: Lọc phần tử từ danh sách
Yêu cầu: Viết hàm nhận danh sách A chứa các số và một số thực x. Hàm trả lại danh sách B chỉ gồm các phần tử $\geq x$.
Hướng dẫn: Khởi tạo danh sách rỗng B bên trong hàm (biến cục bộ), duyệt A, kiểm tra điều kiện rồi bổ sung bằng append().
def Select(A, x):
B = []
for k in range(len(A)):
if A[k] >= x:
B.append(A[k])
return B
Lưu ý phạm vi biến: B là biến cục bộ, chỉ tồn tại trong hàm Select. Sau khi hàm trả về, muốn sử dụng kết quả phải gán vào biến ở chương trình chính, ví dụ: result = Select([3, 1, 5, 2], 2).
Nhiệm vụ 2: Tách từ và chuyển đổi kiểu chữ
Yêu cầu: Viết hàm nhận xâu Str và số c. Tuỳ giá trị c:
c = 0: tách từ, chuyển thành chữ IN HOAc = 1: tách từ, chuyển thành chữ in thườngc = 2: tách từ, viết hoa kí tự đầu mỗi từ
Các phương thức cần dùng: upper(), lower(), title(), split()
def Tach_tu(Str, c):
A = Str.split()
for k in range(len(A)):
if c == 0:
A[k] = A[k].upper()
if c == 1:
A[k] = A[k].lower()
if c == 2:
A[k] = A[k].title()
return A
Nhiệm vụ 3: Chương trình phân loại số nguyên bằng nhiều hàm
Yêu cầu: Viết chương trình gồm 3 hàm:
- Nhập dãy số nguyên (cách nhau bởi dấu cách) → danh sách
A - Trích danh sách
Bgồm các phần tử $> 0$ - Trích danh sách
Cgồm các phần tử $< 0$
def Nhap_Dulieu():
s = input("Nhập các số nguyên cách nhau bởi dấu cách: ")
A = s.split()
for k in range(len(A)):
A[k] = int(A[k])
return A
def getB(A):
B = []
for x in A:
if x > 0:
B.append(x)
return B
def getC(A):
C = []
for x in A:
if x < 0:
C.append(x)
return C
# Chương trình chính
A = Nhap_Dulieu()
print("Danh sách A:", A)
B = getB(A)
C = getC(A)
print("Danh sách B:", B)
print("Danh sách C:", C)
Lưu ý phạm vi biến: Mỗi hàm có biến cục bộ riêng (B trong getB, C trong getC). Chương trình chính nhận kết quả qua giá trị trả về (return) chứ không truy cập trực tiếp vào biến cục bộ.
III. Phương pháp giải các dạng bài tập
Dạng 1: Viết hàm trích xuất và xử lý dữ liệu từ danh sách
Phương pháp chung:
- Tạo danh sách kết quả rỗng bên trong hàm (biến cục bộ).
- Duyệt danh sách đầu vào bằng
forkết hợprange(len(...))hoặc duyệt trực tiếp phần tử. - Kiểm tra điều kiện → dùng
append()để bổ sung phần tử phù hợp. - Trả kết quả bằng
return. Nếu cần trả nhiều danh sách →return B, C.
Bài mẫu 1 – Luyện tập 1:
Viết hàm nhận danh sách sList gồm các xâu kí tự, trả về danh sách cList gồm kí tự đầu tiên của mỗi xâu tương ứng.
Lời giải:
def lay_ki_tu_dau(sList):
cList = []
for s in sList:
cList.append(s[0])
return cList
# Ví dụ
print(lay_ki_tu_dau(["Hello", "World", "Python"]))
# Kết quả: ['H', 'W', 'P']
Bài mẫu 2 – Luyện tập 2:
Viết hàm Tach_day() nhận danh sách A, trả về danh sách B gồm các phần tử có chỉ số chẵn và danh sách C gồm các phần tử có chỉ số lẻ.
Lời giải:
def Tach_day(A):
B = []
C = []
for k in range(len(A)):
if k % 2 == 0:
B.append(A[k])
else:
C.append(A[k])
return B, C
# Ví dụ
B, C = Tach_day([10, 20, 30, 40, 50])
print("B:", B) # B: [10, 30, 50] (chỉ số 0, 2, 4)
print("C:", C) # C: [20, 40] (chỉ số 1, 3)
Dạng 2: Viết hàm trả về nhiều giá trị kết hợp thuật toán
Phương pháp chung:
- Python cho phép hàm trả về nhiều giá trị bằng cú pháp
return giá_trị_1, giá_trị_2. - Bên ngoài hàm, nhận kết quả bằng:
kq1, kq2 = tên_hàm(...). - Áp dụng thuật toán phù hợp với bài toán (ví dụ: thuật toán Euclid cho ƯCLN).
- Tận dụng các công thức liên hệ để tính nhanh (ví dụ: $\text{ƯCLN}(m, n) \times \text{BCNN}(m, n) = m \times n$).
Bài mẫu – Vận dụng 1:
Viết hàm có hai tham số đầu vào m, n. Đầu ra trả lại ƯCLN và BCNN.
Gợi ý: $\text{ƯCLN}(m, n) \times \text{BCNN}(m, n) = m \times n$
Lời giải:
def UCLN_BCNN(m, n):
a, b = m, n
while b != 0:
a, b = b, a % b
ucln = a
bcnn = m * n // ucln
return ucln, bcnn
# Ví dụ
u, b = UCLN_BCNN(12, 18)
print("ƯCLN:", u) # ƯCLN: 6
print("BCNN:", b) # BCNN: 36
Giải thích:
- Dùng thuật toán Euclid: chia lấy dư liên tục cho đến khi
b = 0, lúc đóachính là ƯCLN. - Từ công thức: $\text{BCNN} = \dfrac{m \times n}{\text{ƯCLN}}$
Dạng 3: Viết chương trình kiểm tra tính hợp lệ của dữ liệu
Phương pháp chung:
- Tách chức năng thành hàm riêng: hàm nhập liệu, hàm kiểm tra, chương trình chính điều phối.
- Xét đầy đủ các trường hợp hợp lệ/không hợp lệ.
- Với bài toán ngày tháng: cần kiểm tra tháng (1–12), ngày (tuỳ tháng), và xử lý năm nhuận.
Quy tắc năm nhuận:
- Năm chia hết cho 4 và không chia hết cho 100 → nhuận
- Hoặc năm chia hết cho 400 → nhuận
Bài mẫu – Vận dụng 2:
Viết chương trình nhập day, month, year từ bàn phím (cách nhau bởi dấu cách). Kiểm tra và in ra ngày đó hợp lệ hay không.
Lời giải:
def kiem_tra_ngay(day, month, year):
if year < 1:
return False
if month < 1 or month > 12:
return False
# Xác định số ngày tối đa của tháng
if month in [1, 3, 5, 7, 8, 10, 12]:
max_day = 31
elif month in [4, 6, 9, 11]:
max_day = 30
elif month == 2:
# Kiểm tra năm nhuận
if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0):
max_day = 29
else:
max_day = 28
if day < 1 or day > max_day:
return False
return True
# Chương trình chính
s = input("Nhập day month year cách nhau bởi dấu cách: ")
parts = s.split()
day = int(parts[0])
month = int(parts[1])
year = int(parts[2])
if kiem_tra_ngay(day, month, year):
print("Ngày hợp lệ")
else:
print("Ngày không hợp lệ")
Ví dụ chạy thử:
| Đầu vào | Kết quả |
|---|---|
29 2 2024 |
Ngày hợp lệ (2024 là năm nhuận) |
29 2 2023 |
Ngày không hợp lệ (2023 không nhuận) |
31 4 2025 |
Ngày không hợp lệ (tháng 4 chỉ có 30 ngày) |
15 8 2000 |
Ngày hợp lệ |
IV. Sơ đồ tư duy
PHẠM VI CỦA BIẾN
- Biến cục bộ (khai báo trong hàm)
- 1.1. Chỉ tồn tại và hoạt động bên trong hàm chứa nó
- 1.2. Hàm kết thúc → biến bị huỷ
- 1.3. Gọi bên ngoài hàm → lỗi
NameError - 1.4. Tham số hàm cũng là biến cục bộ
- Biến toàn cục (khai báo ngoài hàm)
- 2.1. Hàm có thể đọc giá trị của biến toàn cục
- 2.2. Hàm không thể gán/thay đổi biến toàn cục (mặc định)
- 2.3. Nếu gán trong hàm → Python tạo biến cục bộ mới, biến ngoài không đổi
- Từ khoá
global- 3.1. Cho phép hàm thay đổi giá trị biến toàn cục
- 3.2. Cú pháp:
global tên_biếnđặt ở đầu hàm - 3.3. Sau đó mọi thay đổi trong hàm đều tác động đến biến ngoài
- Trùng tên biến
- 4.1. Biến trong hàm và biến ngoài hàm cùng tên → hai biến khác nhau
- 4.2. Biến cục bộ “che” biến toàn cục trong phạm vi hàm

Thầy Phạm Thành Danh
(Người kiểm duyệt, ra đề)
Chức vụ: Trưởng ban biên soạn môn Tin Học THPT
Trình độ: Cử nhân Sư phạm Tin học, Chứng chỉ hạng II, Chứng chỉ Tin học, Ngoại ngữ B1
Kinh nghiệm: 8+ năm kinh nghiệm tại Trường THPT Thuận Hóa
