Toán tử chỉ là ký hiệu cho hành động
Toán tử (operator) là một ký hiệu (hoặc một từ khóa ngắn) bảo Python làm gì đó với một hoặc hai giá trị: cộng chúng, so sánh chúng, kiểm tra cái này có chứa cái kia không. Bạn đã biết vài toán tử từ toán cơ bản; Python có thêm một số cho logic, kiểm tra chứa và định danh.
Chúng ta sẽ đi qua từng nhóm chính.
Toán tử số học
Các toán tử toán học quen thuộc, cộng thêm vài thứ đặc trưng của Python:
Hai điểm trong danh sách này rất dễ quên:
/trả về float kể cả khi cả hai vế là số nguyên.10 / 2cho5.0. Để chia lấy nguyên, dùng//.%là phép chia lấy dư.n % 2 == 0là cách gọn nhất để kiểm trancó chẵn không.
Python tuân theo thứ tự ưu tiên chuẩn của toán học: ** ưu tiên hơn * và /, và hai toán tử này lại ưu tiên hơn + và -. Dấu ngoặc đè lên tất cả:
Cứ dùng dấu ngoặc thoải mái khi có chút nghi ngờ. Chúng chẳng tốn gì và làm ý định rõ ràng.
Toán tử so sánh
Sáu phép so sánh, mỗi phép trả về một boolean:
Python cho phép nối chuỗi các phép so sánh, điều hiếm thấy và rất hữu ích:
Dòng đó đọc là "tuổi ít nhất là 18 và nhỏ hơn 65." Bên dưới, nó tương đương 18 <= age and age < 65, nhưng đọc giống ký hiệu toán học hơn.
Toán tử logic
Viết bằng từ tiếng Anh, không phải ký hiệu:
Hai chi tiết nên biết:
Đánh giá short-circuit. and dừng ở giá trị falsy đầu tiên; or dừng ở giá trị truthy đầu tiên. Vế phải thậm chí không được đánh giá nếu vế trái đã quyết định kết quả. Nhờ đó bạn có thể phòng lỗi một cách an toàn:
and/or trả về giá trị, không phải lúc nào cũng là True/False. Chúng trả về toán hạng đã quyết định kết quả:
Bạn sẽ gặp name = user_input or "anonymous" trong code thực tế: đó là mẫu đặt giá trị mặc định dựa trên hành vi này.
Để xem đầy đủ quy tắc của ba toán tử này, gồm những giá trị nào được coi là falsy, not, and và or xếp thứ tự ưu tiên ra sao, và vì sao and không giống &, hãy xem and, or, not trong Python.
Toán tử gán
= dùng để gán. Các dạng kết hợp gộp một phép tính với phép gán:
Các dạng kết hợp cũng dùng được với chuỗi (s += "more") và list (lst += [4, 5]). Chúng không nhanh hơn cách viết đầy đủ; chỉ ngắn hơn thôi.
Kiểm tra thành viên: in và not in
Kiểm tra một giá trị có nằm trong một tập hợp không:
in dùng được với mọi iterable: list, tuple, set, chuỗi, dict và nhiều thứ khác. Khi tra cứu trên dữ liệu lớn, in trên list là O(n); in trên set hay dict là O(1). Điều đó trở nên quan trọng khi bạn kiểm tra thành viên nhiều lần.
Định danh: is và is not
is kiểm tra hai biến có trỏ tới cùng một đối tượng trong bộ nhớ không, chứ không chỉ là giá trị bằng nhau:
Hầu như lúc nào bạn cũng cần ==. Chỗ duy nhất is thực sự phát huy là khi so với None, True và False:
Quy ước của cộng đồng rất rõ: viết is None, không viết == None. Tương tự với is True (dù bạn hiếm khi cần đến).
Toán tử bitwise (bỏ qua ở lần đọc đầu)
Python còn có các toán tử bitwise (&, |, ^, ~, <<, >>) để thao tác với từng bit của một số nguyên. Chúng hữu ích trong mật mã học, lập trình mạng cấp thấp và một số thuật toán. Ở lần đọc đầu, bạn cứ yên tâm bỏ qua.
Toán tử walrus (:=)
Python 3.8 thêm :=, vừa gán vừa trả về giá trị trong cùng một biểu thức. Hữu ích trong điều kiện khi bạn muốn vừa giữ lại vừa kiểm tra một kết quả:
Không có walrus, bạn sẽ phải gọi len(numbers) hai lần hoặc thêm một dòng. Nó không bắt buộc; hãy dùng ở chỗ nó giúp bớt lặp lại.
Cheat sheet thứ tự ưu tiên toán tử
Từ ưu tiên cao nhất đến thấp nhất, với những toán tử bạn thực sự dùng:
**: lũy thừa*,/,//,%: nhân và chia+,-: cộng và trừ<,<=,>,>=,==,!=: so sánhnotandor
Khi còn phân vân, hãy thêm dấu ngoặc. Rõ ràng luôn hơn khéo léo.
Câu hỏi thường gặp
Python có những loại toán tử chính nào?
Số học (+, -, *, /, //, %, **), so sánh (==, !=, <, <=, >, >=), logic (and, or, not), gán (=, +=, -=, …), kiểm tra thành viên (in, not in) và định danh (is, is not).
== và is trong Python khác nhau thế nào?
== kiểm tra hai giá trị có bằng nhau không. is kiểm tra hai biến có cùng trỏ tới đúng một đối tượng trong bộ nhớ không. Với None, True và False, hãy dùng is vì chúng là singleton. Với mọi thứ khác, == gần như luôn là thứ bạn cần.
Toán tử % làm gì trong Python?
Với số, % là toán tử chia lấy dư (modulo): nó trả về phần dư của phép chia. 17 % 5 là 2. Với chuỗi, đó là cú pháp định dạng kiểu cũ (như "hello %s" % name), nhưng f-string gần như đã thay thế nó.