Chuyển đến nội dung chính

Toán tử trong Python

Hướng dẫn này trình bày các loại toán tử khác nhau trong Python, nạp chồng toán tử, độ ưu tiên và tính kết hợp.
· 9 phút đọc

Khám phá cùng AI

Cũng giống như trong toán học, các ngôn ngữ lập trình như Python có các toán tử. Bạn có thể coi chúng như những hàm cực kỳ đơn giản nằm ở nền tảng của khoa học máy tính. Đây là các phép toán đơn giản nhất mà một chương trình máy tính có thể rút gọn về. Chúng là kiến thức thiết yếu cho bất kỳ ai muốn trở thành Nhà khoa học dữ liệu hoặc Kỹ sư phần mềm.

Trong hướng dẫn này, bạn sẽ tìm hiểu về

Nếu bạn muốn tìm hiểu thêm về những điều cơ bản của Ngôn ngữ lập trình Python, hãy xem khóa học miễn phí Intro to Python for Data Science của chúng tôi.

Toán tử số học

Bạn có lẽ đã quen thuộc với chúng, vì chúng xuất phát từ toán học cơ bản.

Các toán tử số học gồm có cộng (+), trừ (-), nhân (*), chia (/), lũy thừa (**), chia lấy phần nguyên (//) và chia lấy dư (%). Bốn toán tử đầu khá đơn giản; lần lượt là cộng, trừ, nhân và chia, và có lẽ bạn đã quen với chúng.

# Addition
print(5 + 2)

# Subtraction
print(5 - 2)

# Multiplication
print(5 * 2)

# Division
print(5 / 2)
7
3
10
2.5

Ba toán tử còn lại phức tạp hơn một chút. Toán tử lũy thừa có nghĩa là "mũ". Ví dụ, 2 ** 3 nghĩa là 2 được nhân với chính nó 3 lần, nên 2 ** 3 tương đương 2 * 2 * 2, bằng 8.

Chia lấy phần nguyên giống như phép chia thông thường, ngoại trừ việc kết quả luôn được làm tròn xuống. Trong ví dụ dưới đây, 5 chia cho 2 được 2.5. Nhưng vì là chia lấy phần nguyên, 2.5 được làm tròn xuống còn 2.

Cuối cùng, phép chia lấy dư là phần dư sau phép chia. Với 5%2, số 2 chỉ "lọt" được hai lần vào 5, nên phần dư là 1.

# Exponent
print(5 ** 2)
# This is the same as 5 * 5

# Floor Division
print(5 // 2)

# Modulus
print(5 % 2)
25
2
1

Trong Python, toán tử cộng cũng có thể dùng để nối chuỗi. Nghĩa là chúng sẽ được ghép thành một chuỗi duy nhất, ví dụ:

firstName = "Théo"

introduction = "Hi, my name is " + firstName + "."

print(introduction)
Hi, my name is Théo.

Toán tử gán

Nếu bạn đã có chút kinh nghiệm lập trình, chắc chắn bạn đã từng dùng toán tử gán. Chúng gán một giá trị nhất định cho biến. Toán tử được dùng nhiều nhất là =. Để dùng, chỉ cần gõ tên biến bạn muốn gán giá trị mới, tiếp theo là =, rồi đến giá trị cần gán. Ví dụ, nếu bạn muốn gán giá trị 100 cho biến balance, bạn có thể làm như sau:

balance = 100
print(balance)
100

Nếu bạn muốn tăng giá trị của balance thêm 10, bạn có thể dùng balance += 10. Câu lệnh này tương đương balance = balance + 10, nhưng ngắn gọn hơn nhiều.

balance += 10
print(balance)
110

Tương tự với -=, balance -= 10 giống như balance = balance - 10:

print(balance)
balance -= 10
print(balance)
110
100

Các toán tử gán khác hoạt động theo đúng cách tương tự. Bao gồm:

  • *=
  • /=
  • **=
  • //=
  • %=

Toán tử so sánh

Bạn có thể dùng các toán tử so sánh để, đúng như tên gọi, so sánh giá trị của các biến. Chúng luôn trả về một giá trị boolean, hoặc True hoặc False. Có sáu toán tử:

  • Bằng: ==
  • Khác: !=
  • Lớn hơn: >
  • Nhỏ hơn: <
  • Lớn hơn hoặc bằng: >=
  • Nhỏ hơn hoặc bằng: <=

Dưới đây là một số ví dụ so sánh:

a = 3
b = 5

print(a == b) # Equal
print(a != b) # Not equal
print(a > b) # Greater than
print(a < b) # Less than
print(a >= b) # Greater than or equal to
print(a <= b) # Less than or equal to
False
True
False
True
False
True

== và != cũng có thể dùng để so sánh chuỗi thay vì số. Các toán tử còn lại không tương thích với chuỗi, vì thật ra không thể nói một chuỗi "lớn hơn" chuỗi khác.

print("Hello" == "World")
print("Python" != "R")
False
True

Toán tử logic

Có thể bạn đã quen với chúng! Trong logic, chúng được gọi là các liên kết logic. Chúng cũng được dùng rộng rãi trong ngôn ngữ tự nhiên. Đó là: and, or và not.

and chỉ trả về True nếu cả hai toán hạng (hai đối tượng boolean bạn đang so sánh) đều True. Ví dụ:

print(True and True)
print(True and False)
print(False and False)
True
False
False

Để hiểu hành vi của toán tử logic này, bạn có thể dùng bảng chân trị:

aba and b
TrueTrueTrue
TrueFalseFalse
FalseTrueFalse
FalseFalseFalse

or là True bất cứ khi nào có ít nhất một toán hạng True.

print(True and True)
print(True and False)
True
False
aba or b
TrueTrueTrue
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse

Lưu ý rằng chúng cũng hoạt động với nhiều hơn hai toán hạng, ví dụ:

print(True and True and True and True)
print(True and True and True and False)
print(False or False or False or False)
print(False or False or False or True)
True
False
False
True

not sẽ trả về giá trị đối nghịch với toán hạng của nó, nên True nếu đưa vào False và ngược lại.

print(not True)
False
anot a
TrueFalse
FalseTrue

Nạp chồng toán tử

Hãy nhớ rằng trước đó, bạn đã thấy + có thể dùng để cộng các số, nhưng cũng có thể dùng để nối, hay kết hợp các chuỗi. Vậy nên + hoạt động khác nhau tùy vào kiểu đối tượng bạn dùng. Nhưng không phải lúc nào cũng vậy. Đôi khi, toán tử bạn đang dùng đơn giản là không hỗ trợ kiểu đối tượng bạn muốn áp dụng.

Đây là một ví dụ. Giả sử bạn có hai đối tượng Dog, ozzy và filou. Chúng thuộc lớp Dog bên dưới. Bạn có thể coi lớp như một bản thiết kế cho việc đối tượng phải trông như thế nào và hành xử ra sao. Trong trường hợp này, các đối tượng Dog có tên, tuổi và chiều cao. Sau khi lớp được định nghĩa, bạn có thể khởi tạo các đối tượng. Một trong số đó là Ozzy, 3 tuổi và cao 30 cm. Còn lại là Filou, 5 tuổi và cao 65 cm.

Ví dụ này sử dụng khái niệm Lập trình hướng đối tượng. Nếu bạn muốn tìm hiểu thêm, hãy đọc hướng dẫn của chúng tôi về Lập trình hướng đối tượng trong Python

Giả sử bạn muốn so sánh hai chú chó bằng toán tử lớn hơn: >. Điều này sẽ không hoạt động. Bạn sẽ nhận được lỗi '>' not supported between instances of 'Dog' and 'Dog'. Điều đó có nghĩa là > không biết cách so sánh các đối tượng của lớp Dog.

class Dog:

    def __init__(self, name, age, height):  
        self.name = name
        self.age = age
        self.height = height

ozzy = Dog("Ozzy", 3, 30)
filou = Dog("Filou", 5, 65)

print(filou > ozzy)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

<ipython-input-96-428069ab24cc> in <module>()
      9 filou = Dog("Filou", 5, 65)
     10
---> 11 print(filou > ozzy)


TypeError: '>' not supported between instances of 'Dog' and 'Dog'

May mắn là với nạp chồng toán tử, bạn có thể định nghĩa hành vi của toán tử khi được gọi trên các đối tượng Dog. Trong trường hợp này, cần định nghĩa một phương thức tên __gt__, nghĩa là "greater than" (lớn hơn), nhận vào hai đối số. Vì chúng ta muốn so sánh những chú chó theo chiều cao, phương thức sẽ trả về self.height > other.height.

class Dog:

    def __init__(self, name, age, height):  
        self.name = name
        self.age = age
        self.height = height

    def __gt__(self,other):
        return self.height > other.height

ozzy = Dog("Ozzy", 3, 30)
filou = Dog("Filou", 5, 65)

print(filou > ozzy)
print(ozzy > filou)
True
False

Độ ưu tiên

Khi bạn kết hợp nhiều toán tử, mọi thứ có thể trở nên rắc rối. Hãy xem ví dụ dưới đây:

a = 2
b = 3
c = 9

a ** b > 5 and c - a // b >= 9 or b ** 2 == c
True

Làm sao bạn biết cái nào sẽ được thực thi trước? Bạn nên đọc một dòng mã có nhiều ký hiệu như thế nào? Nó được thực thi từ trái sang phải hay có một thứ tự cụ thể nào đó?

Đây là lúc độ ưu tiên phát huy tác dụng. Toán tử trong Python được thực thi theo một thứ tự rất cụ thể, và một số toán tử có mức ưu tiên cao hơn những toán tử khác.

Trong bảng sau, bạn có thể thấy thứ tự ưu tiên của các toán tử, từ trên xuống dưới. Các quy tắc này giống trong toán học, nơi một số phép tính trong công thức phải được thực hiện trước những phép khác.

Độ ưu tiênToán tửMô tả
1**lũy thừa
2*, /, %, //nhân, chia, chia lấy dư, chia lấy phần nguyên
3+, -cộng, trừ
4>, <, >=, <=so sánh
5==, !=bằng/khác
6= %= /= //= -= += *= **=gán
7and, or, notlogic

Tính kết hợp

Bạn đã thấy rằng độ ưu tiên rất quan trọng! Nhưng còn những toán tử nằm cùng một mức ưu tiên, như nhân và chia thì sao? Chúng có được thực thi cùng lúc không? Không. *, \, % và \\ được thực thi từ trái sang phải, trong khi ** được thực thi từ phải sang trái. Điều này được gọi là tính kết hợp.

Hãy xem ví dụ sau. Trong trường hợp này, các toán tử sẽ được thực thi từ trái sang phải, và kết quả là 3.

print(5 * 2 // 3)
3

Tuy nhiên, bằng cách thêm dấu ngoặc, bạn có thể thay đổi thứ tự thực thi các toán tử. Đó là tính kết hợp, hoạt động giống như trong toán học. Bất cứ thứ gì trong ngoặc sẽ được tính trước. Trong trường hợp này, phép chia lấy phần nguyên được thực hiện trước, sau đó mới đến phép nhân.

print(5 * (2 // 3))

Kết luận

Bây giờ bạn đã biết toán tử là gì, cách sử dụng và cách chúng hoạt động. Bạn cũng đã học về nạp chồng, độ ưu tiên và tính kết hợp. Bạn đang đi đúng hướng để trở thành một cao thủ Python! Nếu muốn học thêm nữa, đừng ngần ngại xem khóa học Intermediate Python for Data Science của chúng tôi.

Chủ đề

Liên quan