ตัวดำเนินการ Python: เลขคณิต // และ %, การเปรียบเทียบ, and/or/not และ python round
ตัวดำเนินการ / ใน Python ให้ผลลัพธ์เป็น float เสมอ // ให้ส่วนจำนวนเต็มที่ปัดลง % ให้เศษ และ ** คือการยกกำลัง ฟังก์ชัน round(x, n) ปัดเศษถึง n ตำแหน่งแบบธนาคาร: round(2.5) ได้ 2 และ round(3.5) ได้ 4 ส่วนการปัดขึ้นและลงเป็นจำนวนเต็มใช้ math.ceil และ math.floor ค่าสัมบูรณ์ใช้ abs
ตัวดำเนินการ (operator) ใน Python คือสัญลักษณ์ที่เปลี่ยนค่าหนึ่งให้กลายเป็นอีกค่าหนึ่ง เช่น + ใช้บวก // ใช้หารแบบได้จำนวนเต็ม และ and ใช้เชื่อมเงื่อนไข ด้านล่างเป็นรายการตัวดำเนินการทั้งหมดพร้อมตัวอย่าง ความต่างระหว่าง / กับ // ตรรกะของ and, or, not และฟังก์ชันปัดเศษ ได้แก่ python round, math.ceil, math.floor และ abs ตัวอย่างทั้งหมดนำไปวางใน REPL และลองรันได้เลย
รายการตัวดำเนินการใน Python
ตัวดำเนินการแบ่งเป็นกลุ่มตามหน้าที่ ไม่จำเป็นต้องท่องตารางทั้งหมด ในโค้ดจริงที่พบบ่อยที่สุดคือเลขคณิต การเปรียบเทียบ และการเชื่อมตรรกะ
| กลุ่ม | ตัวดำเนินการ | ตัวอย่าง |
|---|---|---|
| เลขคณิต | + - * / // % ** | 7 // 2 → 3 |
| การเปรียบเทียบ | == != < > <= >= | 3 < 5 → True |
| ตรรกะ | and or not | not True → False |
| ความเป็นอัตลักษณ์ | is, is not | x is None |
| การเป็นสมาชิก | in, not in | "ก" in "กาแฟ" → True |
| การกำหนดค่า | = += -= *= /= //= %= **= | total += 250 |
| walrus | := | if (n := len(s)) > 10: |
| ระดับบิต | & | ^ ~ << >> | 5 & 3 → 1 |
ตัวดำเนินการเลขคณิต
การบวก ลบ และคูณทำงานเหมือนในวิชาคณิตศาสตร์ระดับโรงเรียน หากมี float อยู่ในนิพจน์ ผลลัพธ์ก็จะเป็น float ด้วย เช่น 2 + 1.0 ได้ 3.0 จำนวนเต็มใน Python ไม่มีการล้นค่า 2 ** 100 คำนวณได้อย่างแม่นยำไม่ว่าจะมีกี่หลักก็ตาม
>>> 250 + 120
370
>>> 12.5 * 3
37.5
>>> 2 ** 10
1024
>>> 2 ** 0.5
1.4142135623730951
การยกกำลังใน Python: ตัวดำเนินการ **
การยกกำลังใช้เครื่องหมายดอกจันสองตัว ไม่ใช่ ^ เพราะใน Python เครื่องหมาย ^ หมายถึง XOR ระดับบิต ดังนั้น 2 ^ 3 จะได้ 1 ไม่ใช่ 8 เลขยกกำลังเป็นเศษส่วนให้ค่ารากได้ เช่น 9 ** 0.5 ได้ 3.0 มีฟังก์ชัน pow(x, y) ที่ทำงานเหมือนกัน และรับอาร์กิวเมนต์ที่สามเพื่อหาเศษได้ด้วย: pow(2, 10, 1000) ได้ 24
ควรระวังลำดับความสำคัญ ** ทำงานก่อนเครื่องหมายลบหน้าตัวเลข ดังนั้น -2 ** 2 ได้ -4 หากต้องการกำลังสองของจำนวนลบ ให้ใส่วงเล็บ: (-2) ** 2
// ใน Python หมายถึงอะไร: การหาร /, // และ %
Python มีการหารสองแบบ และนี่คือแหล่งที่มาของความประหลาดใจหลักสำหรับมือใหม่ การหารปกติ / ให้ผลเป็น float เสมอ แม้หารลงตัวพอดี การหารแบบจำนวนเต็ม // ตัดส่วนเศษทศนิยมทิ้ง (ปัดลงเสมอ จึงเรียกว่า floor division) และ % ให้เศษที่เหลือ ดังนั้นถ้าเห็น // ในโค้ด Python ให้อ่านว่า "หารแล้วปัดลงเป็นจำนวนเต็ม" ไม่ใช่คอมเมนต์แบบในภาษา C หรือ JavaScript ซึ่ง Python ใช้เครื่องหมาย # แทน
>>> 7 / 2
3.5
>>> 8 / 2
4.0
>>> 7 // 2
3
>>> 7 % 2
1
การหารจำนวนเต็ม // และเศษ %: ตัวอย่างใช้งาน
คู่ // กับ % ใช้แก้โจทย์ประเภท «มีกี่ชุดเต็มและเหลือเท่าไร» ในคอร์ส แอปติดตามค่าใช้จ่ายเก็บเงินเป็นหน่วยสตางค์เพื่อไม่ให้สูญเสียความแม่นยำ แล้วแยกยอดเป็นบาทและสตางค์:
satang = 125050 # เก็บเงินเป็นสตางค์
baht = satang // 100 # 1250 — บาทเต็ม
rest = satang % 100 # 50 — เศษ
print(baht, rest) # 1250 50
print(40 // 7, "สัปดาห์กับ", 40 % 7, "วัน") # 5 สัปดาห์กับ 5 วัน
ฟังก์ชันในตัว divmod ให้ผลทั้งสองค่าพร้อมกัน: divmod(125050, 100) ได้ทูเพิล (1250, 50) เศษยังใช้ตรวจสอบเลขคู่ได้ด้วย: n % 2 == 0 เป็นจริงเมื่อ n เป็นเลขคู่
จำนวนลบ: // ปัดลง
ตัวดำเนินการ // ไม่ได้แค่ตัดเศษทิ้ง แต่ปัดลงไปหาลบอนันต์ สำหรับจำนวนบวกไม่มีความต่าง แต่สำหรับจำนวนลบจะต่าง เครื่องหมายของเศษ % ใน Python จะตรงกับเครื่องหมายของตัวหาร ดังนั้นสมการ a == (a // b) * b + a % b เป็นจริงเสมอ
>>> -7 // 2
-4
>>> -7 % 2
1
>>> int(-7 / 2) # ตัดเศษทิ้ง ไม่ได้ปัดลง
-3
หารด้วยศูนย์: ได้ข้อผิดพลาดอะไร
การหารด้วยศูนย์ด้วยตัวดำเนินการทั้งสามแบบจะเกิดข้อยกเว้น ZeroDivisionError ใช้ได้ทั้งกับจำนวนเต็มและจำนวนทศนิยม ดักจับได้ด้วย try/except หรือตรวจสอบตัวหารล่วงหน้า
>>> 10 / 0
Traceback (most recent call last):
...
ZeroDivisionError: division by zero
>>> count = 0
>>> avg = 1500 / count if count else 0
>>> avg
0
ตัวดำเนินการเปรียบเทียบ
การเปรียบเทียบให้ผลเป็น True หรือ False การเช็กความเท่ากันใช้เครื่องหมาย == สองตัว ส่วนเครื่องหมาย = ตัวเดียวคือการกำหนดค่า สตริงถูกเทียบทีละอักขระตามรหัสของอักขระ ดังนั้น "B" < "a" เป็นจริง เพราะอักษรตัวพิมพ์ใหญ่มาก่อนตัวพิมพ์เล็ก
>>> 250 == 250.0
True
>>> 3 != 4
True
>>> 1 < 5 <= 10 # การเปรียบเทียบต่อเนื่อง: 1 < 5 and 5 <= 10
True
>>> 0.1 + 0.2 == 0.3
False
การเปรียบเทียบต่อเนื่องอย่าง 0 <= x < 100 เป็นความสะดวกของ Python ไม่ต้องเขียน and ส่วนบรรทัดสุดท้ายเตือนถึงความคลาดเคลื่อนของจำนวนทศนิยม: 0.1 + 0.2 ได้ 0.30000000000000004 ให้เปรียบเทียบจำนวนทศนิยมด้วย math.isclose(a, b) และเก็บเงินเป็นสตางค์หรือใช้ Decimal
ตัวดำเนินการตรรกะ and, or, not
ตัวดำเนินการตรรกะใน Python เขียนเป็นคำ ไม่ใช่สัญลักษณ์ && และ || เหมือนภาษาอื่น and เป็นจริงเมื่อทั้งสองฝั่งเป็นจริง or เป็นจริงเมื่ออย่างน้อยหนึ่งฝั่งเป็นจริง และ not กลับค่า
| a | b | a and b | a or b | not a |
|---|---|---|---|---|
| True | True | True | True | False |
| True | False | False | True | False |
| False | True | False | True | True |
| False | False | False | False | True |
ลำดับความสำคัญ: not ก่อน แล้ว and และ or ตามลำดับ นิพจน์ True or False and False ได้ True เพราะ and ถูกคำนวณก่อน ในเงื่อนไขที่ซับซ้อนให้ใส่วงเล็บ เพื่อให้อ่านง่ายทั้งตัวคุณเองและเพื่อนร่วมทีม
and และ or คืนค่าอะไรกันแน่
and และ or ไม่จำเป็นต้องคืนค่า True หรือ False แต่คืนค่าหนึ่งในตัวถูกดำเนินการ or ให้ค่าจริงตัวแรก (หรือตัวสุดท้ายถ้าไม่มีค่าจริงเลย) ส่วน and ให้ค่าเท็จตัวแรก (หรือตัวสุดท้าย) ค่าที่ถือว่าเป็นเท็จคือ 0, 0.0, สตริงว่าง, คอลเลกชันว่าง, None และ False
>>> name = ""
>>> name or "แขก"
'แขก'
>>> 5 and 0
0
>>> not ""
True
การคำนวณเป็นแบบขี้เกียจ (lazy) ถ้าผลลัพธ์ชัดเจนจากฝั่งซ้ายแล้ว ฝั่งขวาจะไม่ถูกคำนวณ ดังนั้น count and total / count จะไม่เกิดข้อผิดพลาดหารด้วยศูนย์เมื่อ count == 0 ตัวดำเนินการ not ต่างจากอีกสองตัวตรงที่คืนค่า bool เสมอ
ตัวดำเนินการ is และ in
== เปรียบเทียบค่า ส่วน is ตรวจว่าชื่อสองชื่อชี้ไปยังอ็อบเจกต์เดียวกันหรือไม่ ตะกร้าว่างสองใบที่เท่ากันก็ไม่ใช่อ็อบเจกต์เดียวกัน ที่เดียวที่ต้องใช้ is เป็นประจำคือการตรวจค่า None: if x is None
>>> a = [250, 120]
>>> b = [250, 120]
>>> a == b, a is b
(True, False)
>>> c = a
>>> c is a
True
อย่าใช้ is เปรียบเทียบตัวเลขและสตริง บางครั้งมัน «ทำงานได้» เพราะการแคชอ็อบเจกต์ภายใน แต่ผลลัพธ์ขึ้นกับการทำงานของอินเทอร์พรีเตอร์ และ Python จะแสดง SyntaxWarning กับโค้ดอย่าง x is 5
ตัวดำเนินการ in ตรวจการมีอยู่ ได้แก่ สตริงย่อยในสตริง องค์ประกอบในลิสต์ หรือคีย์ในดิกชันนารี not in คือการตรวจแบบกลับกัน
>>> "กาแฟ" in "กาแฟ กับนม"
True
>>> "อาหาร" in {"อาหาร": 450, "แท็กซี่": 300}
True
>>> 5 not in [1, 2, 3]
True
ตัวดำเนินการกำหนดค่าและ walrus :=
ตัวดำเนินการแบบรวม เช่น +=, -=, *=, //= และอื่นๆ เป็นทางลัด: total += 250 เท่ากับ total = total + 250 ใน Python ไม่มีตัวดำเนินการ ++ และ -- การเขียน x++ จะเกิดข้อผิดพลาดทางไวยากรณ์
walrus operator := (ตั้งชื่อตามความคล้ายกับงาของวอลรัส) กำหนดค่าไว้ภายในนิพจน์ มีประโยชน์เมื่อต้องใช้ค่านั้นทั้งตรวจสอบและนำไปใช้ต่อ:
items = ["กาแฟ", "แท็กซี่", "อาหาร", "หนัง"]
if (n := len(items)) > 3:
print(f"รายจ่ายเยอะเกินไป: {n}")
while (line := input("จำนวนเงิน: ")) != "":
print(int(line) * 2)
หากไม่มี walrus ต้องเรียก len สองครั้งหรือแยกการกำหนดค่าเป็นอีกบรรทัด อย่าใช้บ่อยเกินไป ถ้าบรรทัดอ่านยาก การกำหนดค่าธรรมดาจะดีกว่า
การปัดเศษใน Python: round, ceil, floor
สำหรับการปัดเศษใน Python มีฟังก์ชันในตัว round และฟังก์ชันจากโมดูล math ซึ่งแก้โจทย์ต่างกัน การสับสนระหว่างกันเป็นความผิดพลาดที่พบบ่อย
| ฟังก์ชัน | ทำอะไร | 2.5 | -2.5 | 2.7 |
|---|---|---|---|---|
round(x) | ไปยังค่าที่ใกล้ที่สุด ถ้าอยู่กึ่งกลางไปหาเลขคู่ | 2 | -2 | 3 |
math.floor(x) | ปัดลง ไปหาลบอนันต์ | 2 | -3 | 2 |
math.ceil(x) | ปัดขึ้น ไปหาบวกอนันต์ | 3 | -2 | 3 |
math.trunc(x), int(x) | ตัดทศนิยมทิ้ง เข้าหาศูนย์ | 2 | -2 | 2 |
ฟังก์ชัน round ใน Python และการปัดแบบธนาคาร
ฟังก์ชัน round(x, n) ปัดเศษถึง n ตำแหน่งหลังจุดทศนิยม ถ้าไม่ใส่อาร์กิวเมนต์ที่สอง จะคืนค่าเป็น int ข้อควรระวังหลักคือ python round ปัดแบบ «ธนาคาร» คือเมื่ออยู่กึ่งกลางจะปัดไปยังเลขคู่ที่ใกล้ที่สุด ดังนั้น round(2.5) ได้ 2 และ round(3.5) ได้ 4 วิธีนี้ทำให้ข้อผิดพลาดจากการปัดไม่สะสมไปในทางเดียวเมื่อคำนวณปริมาณมาก
>>> round(2.5), round(3.5)
(2, 4)
>>> round(3.14159, 2)
3.14
>>> round(1250, -2) # ปัดถึงหลักร้อย
1200
>>> round(2.675, 2) # ไม่ใช่ 2.68: ในรูปแบบไบนารีคือ 2.67499...
2.67
หากต้องการการปัดแบบโรงเรียน «กึ่งกลางปัดขึ้น» เช่นในใบเสร็จ ใช้ Decimal กับโหมด ROUND_HALF_UP และส่งตัวเลขเป็นสตริงเพื่อไม่รับความคลาดเคลื่อนของ float มาด้วย:
>>> from decimal import Decimal, ROUND_HALF_UP
>>> Decimal("2.5").quantize(Decimal("1"), ROUND_HALF_UP)
Decimal('3')
>>> Decimal("2.675").quantize(Decimal("0.01"), ROUND_HALF_UP)
Decimal('2.68')
และอีกหนึ่งกฎจากคอร์ส: ปัดเศษเฉพาะตอนแสดงผล ไม่ต้องใช้ round เพื่อพิมพ์ให้สวย f-string ก็พอ: f"{amount:.2f}" แสดงสองตำแหน่ง แต่ค่าของตัวเลขยังคงแม่นยำ
math.ceil และ math.floor: ปัดขึ้นและปัดลง
math.ceil ใช้เมื่อ «ไม่พอ» เป็นสิ่งที่รับไม่ได้ เช่น ต้องสั่งรถบัสกี่คัน หรือมีกี่หน้าในผลการค้นหา ส่วน math.floor ใช้เมื่อนับเฉพาะหน่วยเต็ม ทั้งสองฟังก์ชันคืนค่าเป็น int
import math
guests = 47
seats = 20
print(math.ceil(guests / seats)) # 3 คัน
print(math.floor(9.99)) # 9
print(-(-guests // seats)) # 3 — ceil โดยไม่ใช้ math ด้วยเทคนิค //
โมดูล math มีฟังก์ชันอื่นที่มีประโยชน์ เช่น math.sqrt (รากที่สอง) math.isclose (เปรียบเทียบเศษส่วน) math.pi และ math.gcd ใน Python 3.15 มีโมดูลย่อย math.integer (PEP 791) สำหรับคณิตศาสตร์จำนวนเต็ม ประกอบด้วย comb, factorial, gcd, isqrt, lcm, perm และ math.gcd เดิมกับฟังก์ชันอื่นยังใช้งานได้ตามปกติ
ฟังก์ชัน abs: ค่าสัมบูรณ์ของตัวเลข
abs(x) คืนค่าสัมบูรณ์ คือระยะห่างจากศูนย์โดยไม่สนเครื่องหมาย ไม่ต้อง import เพราะเป็นฟังก์ชันในตัว ใช้ได้กับจำนวนเต็ม ทศนิยม และจำนวนเชิงซ้อน สำหรับ 3+4j จะคืนความยาวของเวกเตอร์ซึ่งเท่ากับ 5.0
>>> abs(-250)
250
>>> abs(-12.5)
12.5
>>> budget, spent = 5000, 5320
>>> abs(budget - spent) # คลาดเคลื่อนไปเท่าไร
320
การใช้งานทั่วไปคือหาผลต่างโดยไม่สนทิศทาง และเปรียบเทียบกับค่าคลาดเคลื่อนที่ยอมรับได้: abs(a - b) < 0.001 สำหรับเศษส่วนแนะนำ math.isclose มากกว่า เพราะคำนึงถึงขนาดของตัวเลขด้วย
ลำดับความสำคัญของตัวดำเนินการ
เมื่อนิพจน์มีตัวดำเนินการหลายตัว Python จะคำนวณตามลำดับความสำคัญจากสูงไปต่ำ:
**- เอกภาคอย่าง
-x,+x,~x * / // %+ -- การเลื่อนบิตและการดำเนินการระดับบิต
- การเปรียบเทียบ
in,is notandor:=
ดังนั้น 2 + 3 * 4 ได้ 14 ส่วน (2 + 3) * 4 ได้ 20 หากไม่แน่ใจให้ใส่วงเล็บ วงเล็บเกินไม่เสียหายอะไร แต่ข้อผิดพลาดจากลำดับความสำคัญหาเจอได้ยากมาก
ข้อผิดพลาดที่พบบ่อยกับตัวดำเนินการ
| ข้อผิดพลาด | ผลที่เกิดขึ้น | วิธีที่ถูกต้อง |
|---|---|---|
if x = 5: | SyntaxError: นี่คือการกำหนดค่า | if x == 5: |
2 ^ 3 แทนการยกกำลัง | XOR ระดับบิต ได้ผล 1 | 2 ** 3 |
คาดหวังจำนวนเต็มจาก 8 / 2 | ได้ 4.0 | 8 // 2 |
x == 1 or 2 | เป็นจริงเสมอ เพราะ or 2 | x in (1, 2) |
คาดหวัง 3 จาก round(2.5) | การปัดแบบธนาคารได้ 2 | Decimal กับ ROUND_HALF_UP |
"5" + 5 | TypeError | int("5") + 5 |
สรุป
จำให้ขึ้นใจว่า / ให้ float เสมอ // ปัดลง % ให้เศษที่มีเครื่องหมายตามตัวหาร และการยกกำลังคือ ** ส่วน and, or, not เขียนเป็นคำและคำนวณแบบขี้เกียจ ส่วน is ใช้ตรวจ None ฟังก์ชัน python round ปัดเข้าเลขคู่ สำหรับการปัดขึ้นและลงมี math.ceil และ math.floor ส่วนค่าสัมบูรณ์ใช้ abs ในคอร์สตัวดำเนินการเหล่านี้ถูกฝึกจริงในแอปติดตามค่าใช้จ่าย ซึ่งเก็บเงินเป็นสตางค์
คำถามที่พบบ่อย
ปัดเศษทศนิยมสองตำแหน่งใน Python ทำอย่างไร?
ใช้ round(x, 2) และถ้าต้องการแค่แสดงผลให้สวย ใช้ f-string แบบ f"{x:.2f}" ซึ่งไม่เปลี่ยนค่าของตัวเลขจริง
ทำไม round(0.5) ใน Python ได้ 0?
เพราะ round ปัดกึ่งกลางไปยังเลขคู่ที่ใกล้ที่สุด และ 0 เป็นเลขคู่ ในทำนองเดียวกัน round(1.5) และ round(2.5) ได้ 2
จะได้ส่วนจำนวนเต็มของการหารใน Python อย่างไร?
ใช้ตัวดำเนินการ //: 17 // 5 ได้ 3 สำหรับจำนวนลบจะปัดลง ดังนั้น -17 // 5 ได้ -4 ถ้าต้องการตัดทศนิยมเข้าหาศูนย์ ใช้ int(-17 / 5)
Python มีตัวดำเนินการ ternary หรือไม่?
มี เรียกว่านิพจน์เงื่อนไข: ค่า_ถ้าจริง if เงื่อนไข else ค่า_ถ้าเท็จ เช่น "คู่" if n % 2 == 0 else "คี่"
& กับ and ใน Python ต่างกันอย่างไร?
and เป็นตัวดำเนินการตรรกะที่คำนวณแบบขี้เกียจ ส่วน & เป็น AND ระดับบิตสำหรับตัวเลข และเป็นการหาส่วนร่วมของเซตสำหรับเซต ในเงื่อนไข if ให้ใช้ and
หัวข้อนี้สอนอย่างละเอียดพร้อมฝึกปฏิบัติในคอร์ส “Python 3.15: от новичка до профи”
ไปที่คอร์ส