Chắc hẳn bạn đã từng nghe câu nói vui “Trong thế giới Python, hầu như việc gì cũng có thể giải quyết chỉ bằng một vài dòng code”. Sự thực là Python mang lại rất nhiều lệnh “kho báu” mà nếu bạn khai thác thành thạo, tốc độ phát triển dự án sẽ nhanh hơn “một nốt nhạc”. Trong bài viết này, chúng ta sẽ cùng khám phá hàng loạt các lệnh trong Python, tính năng, và công cụ Python giúp bạn tối ưu hoá dự án, đem lại trải nghiệm code tốt hơn.
Đọc thêm: Code Python cơ bản: Hướng dẫn chi tiết các lệnh Python cơ bản
Các lệnh trong Python giúp viết code ngắn hơn
enumerate()
Tại sao cần quan tâm?
Không ít lập trình viên mới học Python hay dùng cú pháp:
for i in range(len(my_list)): print(i, my_list[i])
Cách này hoạt động tốt, nhưng hơi dài dòng. enumerate() giúp bạn lấy cả chỉ số (index) và giá trị (value) trong list một cách sạch sẽ hơn:
for index, value in enumerate(my_list): print(index, value)
Ví dụ minh họa với my_list:
my_list = ["apple", "banana", "cherry"] # Cách 1: Dùng range(len()) print("Sử dụng range(len()):") for i in range(len(my_list)): print(i, my_list[i]) # Cách 2: Dùng enumerate() print("\nSử dụng enumerate():") for index, value in enumerate(my_list): print(index, value)
Kết quả khi chạy mã trên:
Sử dụng range(len()): 0 apple 1 banana 2 cherry Sử dụng enumerate(): 0 apple 1 banana 2 cherry |
Dù đầu ra giống nhau, nhưng việc sử dụng enumerate() giúp code ngắn gọn và rõ ràng hơn.
zip()
Tại sao cần quan tâm?
Khi bạn có hai hay nhiều list, và muốn ghép các phần tử tương ứng thành từng cặp (hoặc bộ nhiều giá trị), zip() là vị cứu tinh. Ví dụ:
names = ["Alice", "Bob", "Charlie"] scores = [90, 85, 92] for name, score in zip(names, scores): print(name, score)
Kết quả:
Alice 90 Bob 85 Charlie 92 |
Trong một khảo sát lập trình năm 2021, 60% lập trình viên Python cho biết họ thường xuyên dùng zip() để kết hợp dữ liệu, nhất là khi phải xử lý với nhiều tập dữ liệu song song, như list chứa thông tin sinh viên, list điểm số, list lớp học…
any() và all()
- any() trả về True nếu ít nhất một phần tử trong iterable (list, tuple…) thỏa điều kiện.
- all() trả về True nếu tất cả phần tử trong iterable đều thỏa điều kiện.
Ví dụ nhanh:
numbers = [0, 2, 5, 0] print(any(numbers)) # True, vì có giá trị khác 0 print(all(numbers)) # False, vì có giá trị bằng 0
Hay khi kết hợp với điều kiện:
numbers = [1, 3, 5, 7] print(all(n > 0 for n in numbers)) # True
Kết quả in ra sẽ là True vì tất cả các phần tử trong danh sách [1, 3, 5, 7] đều thỏa mãn điều kiện n > 0.
Walrus Operator (:=)
Tại sao cần quan tâm?
Walrus Operator, hay Toán tử Hà Mã, chính thức ra mắt trong Python 3.8. Nó cho phép bạn gán biến trực tiếp trong biểu thức, thay vì phải tách biệt một dòng gán biến và một dòng if/while/vòng lặp. Ví dụ đơn giản:
if (length := len(my_list)) > 5: print(f"Danh sách này có {length} phần tử, khá dài!")
Lợi ích là code giảm độ rườm rà, nhưng bạn cũng cần cẩn trọng tránh lạm dụng dẫn đến khó đọc. Theo các diễn đàn trên Reddit, chưa có nhiều các lập trình viên Python thường xuyên sử dụng Walrus Operator, vì nhiều người vẫn “ngại” cú pháp mới hoặc sợ gây khó hiểu cho đồng nghiệp.
Các thư viện và các lệnh trong Python hỗ trợ xử lý dữ liệu và tối ưu
collections.Counter
Hầu hết lập trình viên đều gặp tình huống phải đếm tần suất xuất hiện của phần tử trong danh sách. Thay vì dùng vòng lặp kiểm tra từng giá trị, ta có Counter:
from collections import Counter my_list = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'] counter = Counter(my_list) print(counter) # Counter({'apple': 3, 'banana': 2, 'orange': 1})
Các kỹ sư senior thường xuyên sử dụng Counter như một phần cốt lõi để thống kê tần suất khi xử lý các chuỗi, nhật ký (log), hoặc dữ liệu thô.
defaultdict
Đã bao giờ bạn viết code để kiểm tra xem một key đã tồn tại trong dictionary chưa, nếu không tồn tại thì tạo mới, nếu tồn tại thì cập nhật giá trị? defaultdict giúp bạn rút ngắn quy trình đó:
from collections import defaultdict my_dict = defaultdict(int) my_dict['apple'] += 1 my_dict['banana'] += 2 print(my_dict) # defaultdict(<class 'int'>, {'apple': 1, 'banana': 2})
defaultdict còn cho phép bạn gán kiểu mặc định như list, set… giúp code “sạch” hơn. Theo kinh nghiệm của nhiều lập trình viên kỳ cựu, defaultdict tiết kiệm tới 40 – 50% dòng code xử lý logic liên quan đến dictionary phức tạp.
itertools
Đây là “kho báu” chứa hàng loạt công cụ để làm việc với các iterable (list, tuple…). Thư viện này có:
- combinations() để tạo mọi tổ hợp
- permutations() để tạo mọi hoán vị
- product() để tính tích Descartes của nhiều list
- accumulate() để tính tổng lũy tiến…
combinations()
Hàm combinations(iterable, r) dùng để tạo ra mọi tổ hợp (combination) có độ dài r từ iterable. Mỗi tổ hợp được tạo ra không quan tâm thứ tự (tức là (1,2) và (2,1) được xem là cùng một tổ hợp).
Ví dụ:
from itertools import combinations items = [1, 2, 3] combs = combinations(items, 2) # Lấy mọi tổ hợp độ dài 2 print("Tổ hợp độ dài 2 từ [1, 2, 3]:") for c in combs: print(c)
Kết quả:
Tổ hợp độ dài 2 từ [1, 2, 3]: (1, 2) (1, 3) (2, 3) |
permutations()
Hàm permutations(iterable, r) dùng để tạo ra mọi hoán vị (permutation) có độ dài r từ iterable. Khác với combinations(), hoán vị có xét đến thứ tự (tức là (1,2) và (2,1) là hai hoán vị khác nhau).
Ví dụ:
from itertools import permutations items = [1, 2, 3] perms = permutations(items, 2) # Lấy mọi hoán vị độ dài 2 print("Hoán vị độ dài 2 từ [1, 2, 3]:") for p in perms: print(p)
Kết quả:
Hoán vị độ dài 2 từ [1, 2, 3]: (1, 2) (1, 3) (2, 1) (2, 3) (3, 1) (3, 2) |
product()
Hàm product(*iterables, repeat=1) dùng để tạo ra tích Descartes (Cartesian product) của các iterables. Nó sẽ lấy mỗi phần tử của iterable 1 kết hợp với mỗi phần tử của iterable 2, v.v.
Ví dụ 1: Lấy tích Descartes của 2 list:
from itertools import product list1 = [1, 2] list2 = ['A', 'B'] prod = product(list1, list2) print("Tích Descartes của [1, 2] và ['A', 'B']:") for p in prod: print(p)
Kết quả:
Tích Descartes của [1, 2] và [‘A’, ‘B’]: (1, ‘A’) (1, ‘B’) (2, ‘A’) (2, ‘B’) |
Ví dụ 2: Sử dụng tham số repeat:
from itertools import product chars = ['X', 'Y'] # product(chars, repeat=2) sẽ coi như product(chars, chars) # => Tất cả kết hợp 2 ký tự từ ['X', 'Y']. pairs = product(chars, repeat=2) print("Tích Descartes của ['X', 'Y'] x 2 lần:") for pair in pairs: print(pair)
Kết quả:
(‘X’, ‘X’) (‘X’, ‘Y’) (‘Y’, ‘X’) (‘Y’, ‘Y’) |
accumulate()
Hàm accumulate(iterable, func=operator.add, *, initial=None) dùng để tính giá trị lũy tiến trên các phần tử của iterable. Mặc định, nó sẽ cộng dồn (sử dụng phép cộng). Có thể truyền vào phép toán khác (như nhân, max, min, v.v.) để thay đổi cách tính lũy tiến.
Ví dụ 1: Tính lũy tiến với phép cộng (mặc định):
from itertools import accumulate numbers = [1, 2, 3, 4] acc_sum = accumulate(numbers) # Mặc định là phép cộng print("Lũy tiến (cộng) của [1, 2, 3, 4]:") for s in acc_sum: print(s)
Kết quả:
1 3 # (1+2) 6 # (1+2+3) 10 # (1+2+3+4) |
Ví dụ 2: Tính lũy tiến với phép nhân:
from itertools import accumulate import operator numbers = [1, 2, 3, 4] acc_mul = accumulate(numbers, operator.mul) print("Lũy tiến (nhân) của [1, 2, 3, 4]:") for m in acc_mul: print(m)
Kết quả:
1 2 # (1*2) 6 # (1*2*3) 24 # (1*2*3*4) |
Tóm lại:
- combinations(): Lấy mọi tổ hợp (không xét thứ tự).
- permutations(): Lấy mọi hoán vị (có xét thứ tự).
- product(): Tính tích Descartes (kết hợp các phần tử từ nhiều iterable).
- accumulate(): Tính lũy tiến (mặc định là cộng dồn, có thể thay đổi bằng đối số func).
Đây là những hàm hữu ích trong itertools khi làm việc với các thao tác liên quan đến tổ hợp, hoán vị, tích Descartes, và tổng/tích lũy tiến.
map() và filter()
Hai hàm này là “công cụ bỏ túi” cho việc biến đổi hoặc lọc dữ liệu nhanh:
numbers = [1, 2, 3, 4, 5] squared = list(map(lambda x: x*x, numbers)) even = list(filter(lambda x: x % 2 == 0, numbers)) print(squared) # [1, 4, 9, 16, 25] print(even) # [2, 4]
Các lập trình viên thích dùng list comprehension hơn, nhưng map() và filter() vẫn phổ biến trong một số trường hợp có hàm sẵn hoặc khi cần chain nhiều hàm liên tiếp.
Các lệnh trong Python giúp xử lý file và quản lý tài nguyên
with open()
Quên đóng file là “sát thủ thầm lặng” gây rò rỉ tài nguyên. Trong khi nếu dùng with open(), Python sẽ tự động đóng file ngay khi thoát khối lệnh:
with open('data.txt', 'r') as file: data = file.read() # Tại đây file đã được đóng
Các diễn đàn hướng dẫn cho người mới bắt đầu khuyến khích sử dụng with open() thay cho cách mở file truyền thống f = open(), vì sự tiện lợi và an toàn.
os và shutil
Để thao tác với file, thư mục ở cấp hệ thống, bạn không thể bỏ qua hai “thư viện gốc” này:
- os: Tạo, xóa, đổi tên, di chuyển file/thư mục, lấy thông tin môi trường…
- shutil: Sao chép file/thư mục, nén/giải nén, thao tác phức tạp hơn với hệ thống.
Ví dụ:
import os import shutil os.rename('old_name.txt', 'new_name.txt') shutil.copy('new_name.txt', 'backup_name.txt')
Các lệnh trong Python nâng cao
List/Dictionary Comprehension
Đây là một cú pháp giúp tạo List và Dict theo điều kiện một cách nhanh chóng.
List Comprehension
Ví dụ tạo ra list trong range 10 và số đó chia hết cho 2:
numbers = [x for x in range(10) if x % 2 == 0]
Dictionary Comprehension
Tạo ra Dict mới khi mà giá của các loại hoa quả giảm giá đi 10%:
items = {'apple': 10, 'banana': 5, 'orange': 8} discounted = {k: v*0.9 for (k, v) in items.items()}
Trong Python, “code ngắn gọn” không phải lúc nào cũng là mục tiêu tối thượng, nhưng lập trình viên cho biết họ yêu thích comprehension vì tính súc tích và dễ đọc khi dùng đúng bối cảnh.
F-string
F-string (xuất hiện từ Python 3.6) là “vũ khí” định dạng chuỗi. Thay vì:
name = "Alice" age = 25 print("Tên: " + name + ", Tuổi: " + str(age))
Chúng ta có:
print(f"Tên: {name}, Tuổi: {age}")
Bạn thậm chí có thể nhúng hàm:
print(f"Độ dài tên: {len(name)}")
Các Senior Developer khi được được hỏi trên các diễn đàn chuyên môn chuyển sang dùng F-string ngay khi nó ra mắt, vì sự tiện lợi không thể chối cãi.
Decorators (cơ bản)
Decorator cho phép thêm/bớt tính năng vào hàm mà không thay đổi code gốc. Ví dụ một decorator tính thời gian chạy hàm:
import time def timing_decorator(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"Hàm {func.__name__} chạy hết {end - start} giây.") return result return wrapper @timing_decorator def heavy_task(): time.sleep(1) heavy_task() # In ra thời gian chạy
Lập trình viên Python thích sử dụng cú pháp này nhất là trong việc logging, caching (như functools.lru_cache) hoặc kiểm soát truy cập.
Câu hỏi thường gặp về các lệnh trong Python
Tôi nên học lệnh nào trước?
Nếu bạn mới làm quen với Python, hãy bắt đầu từ những lệnh “nhỏ nhưng có võ”:
- enumerate() – cực kỳ hữu dụng khi duyệt list.
- zip() – gộp dữ liệu từ nhiều list.
- with open() – xử lý file an toàn.
Những lệnh này có khả năng áp dụng rộng rãi trong hầu hết dự án.
Python 2 có dùng được các lệnh này không?
- enumerate(), zip(), any(), all(): Đều có trên Python 2.
- Walrus Operator (:=): Chỉ xuất hiện từ Python 3.8+
Ngoài ra, một số thư viện có thể chỉ hỗ trợ phiên bản Python 3 trở lên. Nếu vẫn còn buộc phải dùng Python 2, bạn cần xem kỹ tài liệu hoặc dùng các phiên bản thư viện tương thích.
Khi nào dùng vòng lặp for, khi nào dùng map()/filter() hay comprehension?
- Vòng lặp for: Phù hợp với logic phức tạp, nhiều điều kiện, nhiều biến trung gian.
- Comprehension: Khi bạn muốn truy xuất/biến đổi danh sách một cách gọn, rành mạch.
- map(), filter(): Khi bạn có một hàm rõ ràng cần áp dụng lên mỗi phần tử hoặc cần lọc các giá trị thỏa mãn điều kiện duy nhất.
Code ngắn gọn có luôn tốt hơn không?
Ưu tiên sự rõ ràng, dễ bảo trì. Nếu code trở nên “bí hiểm” khiến đồng đội đọc mãi không hiểu, thì đôi khi vòng lặp for truyền thống lại “an toàn” hơn. Hãy cân bằng giữa “đẹp” và “dễ hiểu”.
Tìm hiểu thêm về các lệnh trong Python ở đâu?
- Tài liệu Python chính thức: Nơi tốt nhất để đọc chi tiết.
- Blog ITviec, Stack Overflow, Reddit: Nguồn chia sẻ kinh nghiệm thực chiến từ cộng đồng.
- PyPI: Cập nhật xu hướng thư viện mới, những bản phát hành quan trọng.
Tổng kết các lệnh trong Python
Python ẩn chứa vô vàn lệnh tưởng chừng nhỏ nhặt, nhưng lại có sức ảnh hưởng lớn đến hiệu suất và cấu trúc code. Từ việc duyệt list với enumerate(), gộp dữ liệu bằng zip(), đến việc “ma thuật hoá” với Walrus Operator hay tô điểm code bằng Decorators, tất cả gộp lại tạo nên một “kho vũ khí” lợi hại, giúp bạn:
- Tiết kiệm thời gian và công sức khi viết các thao tác lặp đi lặp lại.
- Tối ưu code theo hướng ngắn gọn nhưng vẫn rõ ràng.
- Mở rộng khả năng xử lý dữ liệu, quản lý tài nguyên.
Sự khác biệt giữa người mới (Fresher) và người dày dạn kinh nghiệm (Senior) trong Python thường nằm ở tư duy và cách tiếp cận hơn là danh sách các lệnh cụ thể. Trong khi người mới thường chú trọng hoàn thành chức năng cơ bản, người “lão luyện” lại hiểu sâu về cấu trúc ngôn ngữ, biết tối ưu hóa luồng xử lý và viết code mang tính “Pythonic” – ngắn gọn, rõ ràng, dễ bảo trì. Họ không chỉ nắm công cụ sẵn có, mà còn vận dụng chúng một cách linh hoạt, kết hợp với thói quen kiểm soát lỗi chặt chẽ, quản lý tài nguyên hợp lý. Chính những điều này giúp tạo ra khác biệt về hiệu quả, tính ổn định và khả năng mở rộng của sản phẩm cuối cùng.