Python – Toán tử

1.4/5 - (68 votes)

Trong phần này chúng ta sẽ tìm hiểu về các toán tử có trong Python.

Toán tử ở đây là các kí tự dùng để thực thi các phép tính nào đó. Hầu hết các toán tử trong lập trình đều bắt nguồn từ các phép toán trong toán học. Chỉ khác là trong lập trình thì toán tử thao tác với dữ liệu.

Trong Python, toán tử được chia ra làm những loại sau:

  • Toán tử số học
  • Toán tử boolean
  • Toán tử quan hệ
  • Toán tử thao tác bit

Trong một biểu thức toán tử có thể có một hoặc hai toán hạng. Toán hạng là các giá trị hay các biến tham gia vào biểu thức. Toán tử sẽ xử lý các toán hạng và trả về kết quả. Ví dụ a = 1 + c, trong đó dấu = và dấu + là các toán tử, còn a, 1c là các toán hạng.

Dấu + và – trong toán tử cộng trừ có thể được dùng để làm dấu của số. Nhưng thường thì chúng ta chỉ dùng dấu – để biểu diễn số nguyên âm chứ ít ai dùng dấu + để biểu diễn số nguyên dương.

>>> a = 1
>>> -a
-1
>>> -(-a)
1

Toán tử gán

Toán tử gán có kí hiệu là dấu =, ý nghĩa của toán tử này là gán một giá trị cho một biến nào đó. Toán hạng nằm bên trái dấu = sẽ được gán giá trị.

>>> x = 1
>>> x
1

Trong đoạn code trên chúng ta gán x bằng 1.

>>> x = x + 1
>>> x
2

Trong đoạn code kế tiếp thì biểu thức x = x + 1 không có ý nghĩa trong toán học. Nhưng trong lập trình thì hợp lệ. Biểu thức đó có ý nghĩa tăng giá trị của x lên 1. Ở bên phải toán tử, biểu thức x + 1 có giá trị là 2 sẽ được gán cho biến x.

>>> a = b = c = 4
>>> print (a, b, c)
4 4 4

Trong Python và hầu hết các ngôn ngữ lập trình, chúng ta có thể gán 1 giá trị cho nhiều biến cùng một lúc.

>>> 3 = y
  File "<stdin>", line 1
SyntaxError: can't assign to literal

Đoạn code trên báo lỗi vì bạn chỉ có thể gán giá trị hoặc biến cho một biến chứ không thể gán cho một giá trị khác.

Toán tử số học

Bảng dưới đây mô tả các toán tử số học trong Python.

Kí HIỆU TÊN
+ Cộng
- Trừ
* Nhân
/ Chia
// Floor division
% Chia lấy phần dư
** Lũy thừa

Đoạn code dưới đây ví dụ về các toán tử trên.

a = 10
b = 11
c = 12

add = a + b + c
sub = c - a
mult = a * b
div = c / 3

pow = a ** 2

print (add, sub, mult, div)
print (pow)

Tất cả các toán tử này đều có trong toán học.

33 2 110 4.0
100

Kết quả trả về.

print (9 / 3)
print (9 / 4)
print (9 / 4.0)
print (9 // 4.0)
print (9 % 4)

Đoạn code trên ví dụ rõ hơn về phép toán chia.

print (9 // 4.0)

Dòng trên ví dụ về toán tử //, đây là toán tử làm tròn xuống, ví dụ 2.25 hay 2.75 đều được làm tròn về 2.0.

print (9 % 4)

Toán tử % là phép toán lấy phần dư. Ví dụ 9 chia 4 được 2 1.

3.0
2.25
2.25
2.0
1
>>> 'return' + 'of' + 'the' + 'king'
'returnoftheking'

Trong các bài trước, chúng ta đã biết là toán tử cộng có thể được dùng để nối string.

>>> 3 + ' apples'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Chúng ta không thể cộng một số với một string. Kết quả sẽ cho ra một lỗi exception.

>>> str(3) + ' apples'
'3 apples'

Nếu muốn chuyển một số sang chuỗi để nối vào một chuỗi thì chúng ta phải dùng hàm str() để chuyển.

Tuy nhiên toán tử * lại có thể dùng cho chuỗi và số.

>>> 'dollar ' * 5
'dollar dollar dollar dollar dollar '

Toán tử boolean

Trong Python, chúng ta có các toán tử and, or và not. Các toán tử này làm công việc mang tính logic. Chúng thường được dùng trong các câu lệnh if và while.


# andop.py

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

Đoạn code trên ví dụ về các toán tử and. Kết quả chỉ trả về True khi cả hai đều là True.

True
False
False
False

Đoạn code dưới đây ví dụ về toán tử or. Kết quả trả về True khi một trong hai toán hạng là True.

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

Toán tử not chỉ làm việc với một toán hạng. Toán tử này sẽ đảo ngược giá trị từ True thành False và ngược lại.

print (not False)
print (not True)
print (not ( 4 < 3 ))
True
False
True

Hai toán tử andor chỉ xét tới toán hạng thứ hai khi toán hạng thứ nhất thỏa điều kiện. Ví dụ trong toán tử and nếu toán hạng đầu tiên là false thì tự động kết quả trả về sẽ là false chứ không xét toán hạng thứ 2 nữa, còn đối với toán tử or thì nếu toán hạng đầu tiên là True thì lập tức kết quả trả về là True luôn chứ cũng không xét toán hạng thứ hai nữa.

Ví dụ.

x = 10
y = 0

if (y != 0 and x/y < 100):
      print ("a small value")

Đoạn code trên sẽ trả về False vì y khác 10 và toán hạng thứ hai không được xét đến. Nếu không sẽ xảy ra lỗi exception vì chúng ta không thể chia một số cho 0.

Toán tử quan hệ

Các toán tử quan hệ dùng để so sánh các giá trị, kết quả trả về là True hoặc False.

KÍ HIỆU Ý NGHĨA
< Bé hơn
<= Bé hơn hoặc bằng
> Lớn hơn
>= Lớn hơn hoặc bằng
== Bằng
!= or <> Không bằng (khác)
is định danh đối tượng
is not định danh không phải đối tượng

Bảng trên mô tả các toán tử quan hệ.

>>> 3 < 4 True >>> 4 == 3
False
>>> 4 >= 3
True

Chúng ta không chỉ có thể dùng các toán tử quan hệ với các số mà có thể dùng với các đối tượng khác nữa, mặc dù làm thế cũng không ý nghĩa mấy.

>>> "six" == "six"
True
>>> "a" > 6
True
>>> 'a' < 'b'
True

Chúng ta có thể so sánh hai string, hai kí tự hoặc so sánh một string với một số.

>>> 'a' < 'b'

Trong máy tính thì các kí tự này đều mang một mã số bên mình, khi so sánh hai kí tự thì thực chất máy tính so sánh hai mã số này. Mã số của các kí tự này được lưu trong các bảng mã. Mặc định là bảng mã ASCII.

print ('a' < 'b')

print ("a is:", ord('a'))
print ("b is:", ord('b'))

Nếu như bạn muốn biết mã số của các kí tự thì bạn có thể dùng hàm ord().

True
a is: 97
b is: 98

Như vậy trong máy tính khi so sánh hai kí tự ‘a’ và ‘b’ thực chất là so sánh hai số 97 và 98.

>>> "ab" > "aa"
True

Khi so sánh một chuỗi, các kí tự đầu tiên sẽ được so sánh với nhau, nếu chúng bằng nhau, các kí tự thứ 2, thứ 3…. sẽ lần lượt được so sánh. Thực ra chúng ta cũng ít khi so sánh hai chuỗi vì việc này cũng không có ý nghĩa mấy.

print (None == None)
print (None is None)

print (True is True)

print ([] == [])
print ([] is [])

print ("Python" is "Python")

Toán tử == có tác dụng kiểm tra xem hai toán hạng có bằng nhau hay không. Từ khóa is kiểm tra xem toán hạng có phải là một đối tượng kiểu nào đó hay không.

True
True
True
True
False
True

Đoạn tiếp theo có thể sẽ hơi khó hiểu nhưng bạn cũng không cần đọc làm gì 😀

Sự khác nhau giữa toán tử == và từ khóa is là khi chúng được sử dụng trên các đối tượng thì toán tử == sẽ so sánh các giá trị trong khi từ khóa is sẽ so sánh địa chỉ của chúng trong bộ nhớ. Do đó trong biểu thức []==[] kết quả trả về True vì chúng đều là các list rỗng, nhưng []is[] lại cho kết quả False vì chúng là các thực thể khác nhau trong bộ nhớ. Còn đối với các đối tượng None, True thì lại khác, đây là các đối tượng đặc biệt, trong Python chúng là duy nhất, không hề có 2 đối tượng None hay True nên kết quả trả về True. Đối với trường hợp so sánh 2 string ("Python" is "Python") thì do Python tự động tối ưu bộ nhớ nên những string có giá trị giống nhau sẽ được sử dụng chung bộ nhớ, kết quả trả về True.

Toán tử thao tác bit

Đối với loài người chúng ta thì chúng ta sử dụng bộ chữ số hệ thâp phân (tức hệ 10) gồm các chữ số từ 0 đến 9, bộ chữ số này rất tiện cho chúng ta vì mặc nhiên chúng ta có 10 ngón tay và 10 ngón chân. Đối với máy tính thì khác, máy tính chỉ dùng một bộ chữ số đơn giản là hệ nhị phân, chỉ gồm hai chữ số 0 và 1. Các toán tử thao tác bit là các phép toán thực hiện với chữ số nhị phân. Tuy nhiên trong các ngôn ngữ cấp cao như Python chúng ta cũng ít khi dùng đến chúng.

KÍ HIỆU Ý NGHĨA
~ Phép nghịch đảo
^ Phép xor
& Phép and
| Phép or
<< Phép dịch trái
>> Phép dịch phải

Phép nghịch đảo có tác dụng đổi các bit từ 0 sang 1 và ngược lại.

>>> ~7
-8
>>> ~-8
7

Phép nghịch đảo của số 7 là -8. Nếu chúng ta thực hiện nghịch đảo của -8 sẽ lại được 7.

Toán tử and so sánh 2 bit với nhau, kết quả là 1 nếu cả hai là 1, ngược lại thì ra 0.

     00110
  &  00011
   = 00010
>>> 6 & 3
2
>>> 3 & 6
2

Toán tử or so sánh 2 bit với nhau. Nếu một trong hai bit là 1 thì kết quả sẽ ra 1. Nếu cả 2 là 0 thì kết quả ra 0.

     00110
  |  00011
   = 00111

Kết quả của phép toán trên là 00110 hay số 7 trong hệ 10.

>>> 6 | 3
7

Phép toán xor so sánh 2 bit. Nếu cả 2 giống nhau thì ra 0, ngược lại thì ra 1.

     00110
  ^  00011
   = 00101

Kết quả trên ra 00101 hoặc 5 trong hệ 10.

>>> 6 ^ 3
5

TIếp theo là các toán tử dịch bit. Chúng ta có phép dịch bit sang trái và sang phải. Ví dụ với dãy bit 00110 khi dịch sang trái sẽ được 01100, còn dịch sang phải sẽ được 00011. Phép dịch bit sang trái còn mang ý nghĩa là nhân một số cho 2, còn dịch sang phải mang ý nghĩa chia một số cho 2.

     00110
  >>  00001
   = 00011

Trong ví dụ trên, chúng ta có 00110 là số 6 trong hệ 10, khi dịch dang phải 1 bit, chúng ta được dãy bit 00011 hay 3 trong hệ 10. Tức là chúng ta đã chia 6 cho 2 và được 3.

>>> 6 >> 1
3
     00110
  << 00001
   = 01100

Ngược lại cũng với dãy bit 00110 khi dịch trái chúng ta được 01100 tức 12 trong hệ 10. Tức là chúng ta đã nhân 6 cho 2 và được 12.

>>> 6 << 1
12

Toán tử gán bằng

Các toán tử gán bằng bao gồm 2 kí tự, thực chất chúng chỉ là cách viết tắt thôi.

>>> i = 1
>>> i = i + 1
>>> i
2
>>> i += 1
>>> i
3

Toán tử += là một toán tử gán bằng. Ví dụ i += 1 tương đương với i = i + 1. Cách viết này rất được hay dùng.

Dưới đây là một số toán tử gán bằng khác:

-=   *=   /=   //=   %=   **=   &=   |=   ^=   >>=   <<=

Mức độ ưu tiên của toán tử

Khi một biểu thức có nhiều toán tử, chúng sẽ được thực hiện từ các toán tử có độ ưu tiên cao hơn đến thấp hơn.

Ví dụ với biểu thức dưới đây, phép toán * sẽ được thực hiện trước rồi mới đến phép toán +.

3 + 5 * 5

Cũng giống như trong toán, chúng ta có thể tăng mức độ ưu tiên cho một toán tử bằng cặp dấu ().

(3 + 5) * 5

Các toán tử nằm trong cặp dấu () sẽ được ưu tiên thực hiện trước.

Dưới đây là danh sách các toán tử được sắp xếp theo mức độ ưu tiên từ cao xuống thấp.

   unary +  -  ~
   **
   *  /  %
   +  -
   >>  <<
   &
   ^
   |
   <  <= == >=  >  !=  <>  is
   not
   and 
   or

Các toán tử nằm cùng hàng với nhau có mức độ ưu tiên bằng nhau, khi đó chúng sẽ được thực hiện từ trái qua phải.


print (3 + 5 * 5)
print ((3 + 5) * 5)

print (2 ** 3 * 5)
print (not True or True)
print (not (True or True))

Đoạn code trên ví dụ về mức độ ưu tiên của một số toán tử.

print (2 ** 3 * 5)

Phép lấy lũy thừa có mức độ ưu tiên cao hơn phép nhân. Do đó phép tính 2 ** 3 sẽ được thực hiện trước rồi mới nhân cho 5. Kết quả ra 40.

print (not True or True)

Trong dòng trên, toán tử not có độ ưu tiên cao hơn nên sẽ được thực hiện trước sau đó mới đến toán tử or. Kết quả ra True.

28
40
40
True
False

Các toán tử quan hệ có mức độ ưu tiên cao hơn toán tử boolean.

a = 1
b = 2

if (a > 0 and b > 0):
   print ("a and b are positive integers")

Trong đoạn code trên, toán tử and sẽ được thực hiện sau cùng khi 2 toán tử quan hệ đã thực hiện xong.

a and b are positive integers
4.3 3 votes
Article Rating
Subscribe
Thông báo cho tôi qua email khi
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Inline Feedbacks
View all comments
hoàng
hoàng
6 năm trước

cho e hỏi đoạn này:
“Phép nghịch đảo của số 7 là -8. Nếu chúng ta thực hiện nghịch đảo của -8 sẽ lại được 7”
Có thể giải thích giúp e vì sao kết quả lại vậy được không ạ. Em xin cám ơn !