ข้ามไปยังเนื้อหาหลัก
Editor

การตัดช่วง (Slicing) ใน Python: สตริง ลิสต์ และทูเพิล

เริ่มต้น20 นาที6 แบบฝึกหัด80 XP

บทเรียนนี้แปลจากต้นฉบับภาษาอังกฤษRead in EnglishLeer en españolЧитать на русскомLer em portuguêsแจ้งข้อผิดพลาดในการแปล

0/6 แบบฝึกหัด

ลองนึกภาพพิซซ่าที่ตัดเป็น 8 ชิ้น มีหมายเลข 0 ถึง 7 คุณไม่ได้อยากได้พิซซ่าทั้งถาดเสมอไป บางครั้งคุณอยากได้ชิ้นที่ 2 ถึง 5 บางครั้งอยากได้ชิ้นเว้นชิ้น บางครั้งอยากได้แค่สามชิ้นสุดท้าย

การตัดช่วง (slicing) ใน Python ช่วยให้คุณดึงบางส่วนของลำดับข้อมูลใดก็ได้ ไม่ว่าจะเป็นลิสต์ สตริง หรือทูเพิล ด้วยรูปแบบการเขียนที่เรียบง่ายแบบเดียวกัน เป็นหนึ่งในความสามารถที่สวยงามที่สุดของ Python และเมื่อเรียนรู้แล้ว คุณจะใช้มันทุกที่

ในบทเรียนนี้ คุณจะได้เรียนรูปแบบ start:stop:step วิธีทำงานของดัชนีลบ วิธีกลับลำดับข้อมูลใดๆ และรูปแบบการตัดช่วงที่นักพัฒนา Python ใช้กันบ่อยที่สุดในทุกวัน

การตัดช่วงพื้นฐานทำงานอย่างไร

รูปแบบพื้นฐานของการตัดช่วงคือ sequence[start:stop] ซึ่งให้สมาชิกตั้งแต่ดัชนี start ไปจนถึง (แต่ ไม่รวม) ดัชนี stop ให้นึกถึงช่วงครึ่งเปิด (half-open interval)

การตัดช่วงพื้นฐานด้วย start:stop
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']
# Get items at index 1, 2 (stops before 3)
print(fruits[1:3]) # ['banana', 'cherry']
# Get the first three items
print(fruits[0:3]) # ['apple', 'banana', 'cherry']
# Get items from index 2 to the end
print(fruits[2:5]) # ['cherry', 'date', 'elderberry']
ผลลัพธ์
['banana', 'cherry']
['apple', 'banana', 'cherry']
['cherry', 'date', 'elderberry']

กฎ "หยุดก่อนถึง stop" อาจดูแปลกในตอนแรก แต่มีข้อดีที่น่าสนใจ: fruits[0:3] ให้สมาชิก 3 ตัวพอดี สำหรับการตัดช่วงแบบ [start:stop] ธรรมดาที่ 0 <= start <= stop <= len(fruits) จำนวนสมาชิกที่ได้คือ stop - start

การละ start และ stop
numbers = [10, 20, 30, 40, 50, 60]
# First three items (omit start)
print(numbers[:3]) # [10, 20, 30]
# Everything from index 3 onward (omit stop)
print(numbers[3:]) # [40, 50, 60]
# Copy the entire list (omit both)
copy = numbers[:]
print(copy) # [10, 20, 30, 40, 50, 60]
ผลลัพธ์
[10, 20, 30]
[40, 50, 60]
[10, 20, 30, 40, 50, 60]

พารามิเตอร์ step ทำอะไร

รูปแบบเต็มของการตัดช่วงคือ sequence[start:stop:step] step กำหนดว่าจะกระโดดไกลแค่ไหนระหว่างสมาชิกแต่ละตัวที่หยิบ step เป็น 2 คือหยิบเว้นตัว step เป็น 3 คือหยิบทุก ๆ ตัวที่สาม

การใช้พารามิเตอร์ step
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Every other item
print(numbers[::2]) # [0, 2, 4, 6, 8]
# Every other item starting from index 1
print(numbers[1::2]) # [1, 3, 5, 7, 9]
# Every third item
print(numbers[::3]) # [0, 3, 6, 9]
# From index 1 to 7, every 2nd item
print(numbers[1:7:2]) # [1, 3, 5]
ผลลัพธ์
[0, 2, 4, 6, 8]
[1, 3, 5, 7, 9]
[0, 3, 6, 9]
[1, 3, 5]

ถ้าไม่ระบุ start และ stop และ step เป็นบวก การตัดช่วงจะครอบคลุมทั้งลำดับตั้งแต่ต้นจนจบ ส่วน step ที่เป็นลบจะสลับค่าเริ่มต้นเหล่านั้น โดยเริ่มจากท้ายลำดับ ดังที่คุณจะเห็นด้านล่าง คุณต้องระบุค่าเหล่านี้ก็ต่อเมื่ออยากจำกัดช่วงให้แคบลง

ดัชนีลบในการตัดช่วงทำงานอย่างไร

ดัชนีลบนับจากท้ายลำดับ -1 คือสมาชิกตัวสุดท้าย -2 คือตัวรองสุดท้าย และต่อไปเรื่อยๆ คุณใช้ตัวเลขติดลบได้ทุกส่วนของการตัดช่วง ทั้ง start, stop และ step

การตัดช่วงด้วยดัชนีลบ
letters = ['a', 'b', 'c', 'd', 'e', 'f']
# Last three items
print(letters[-3:]) # ['d', 'e', 'f']
# Everything except the last two
print(letters[:-2]) # ['a', 'b', 'c', 'd']
# From second-to-last to last
print(letters[-2:]) # ['e', 'f']
ผลลัพธ์
['d', 'e', 'f']
['a', 'b', 'c', 'd']
['e', 'f']

ดัชนีลบมีประโยชน์มากเมื่อคุณต้องการสมาชิกโดยนับจากท้าย เช่น my_list[-3:] ให้สมาชิกสามตัวสุดท้ายเสมอ ไม่ว่าลิสต์จะยาวแค่ไหน

การตัดช่วงสตริงด้วยดัชนีลบ
word = 'Python'
# Remove first and last character
print(word[1:-1]) # ytho
# Last 4 characters
print(word[-4:]) # thon
# First 2 characters
print(word[:2]) # Py
ผลลัพธ์
ytho
thon
Py

วิธีกลับลำดับข้อมูลด้วย [::-1]

step ที่ติดลบบอก Python ให้เดินถอยหลัง รูปแบบที่พบบ่อยที่สุดคือ [::-1] ซึ่งกลับลำดับข้อมูลทั้งหมด ไม่มี start ไม่มี stop และ step เป็น -1 คือเดินจากท้ายไปต้นเท่านั้นเอง

การกลับลำดับด้วย [::-1]
# Reverse a list
numbers = [1, 2, 3, 4, 5]
print(numbers[::-1]) # [5, 4, 3, 2, 1]
# Reverse a string
word = 'hello'
print(word[::-1]) # olleh
# Reverse a tuple
coords = (10, 20, 30, 40)
print(coords[::-1]) # (40, 30, 20, 10)
ผลลัพธ์
[5, 4, 3, 2, 1]
olleh
(40, 30, 20, 10)

คุณใช้ step ที่ติดลบร่วมกับ start และ stop เพื่อกลับลำดับแค่บางส่วนได้ เมื่อใช้ step ติดลบ start ควรมากกว่า stop เพราะคุณกำลังเดินถอยหลัง

step ติดลบพร้อม start และ stop
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Reverse items from index 7 down to index 2 (not including 2)
print(numbers[7:2:-1]) # [7, 6, 5, 4, 3]
# Every other item, reversed
print(numbers[::-2]) # [9, 7, 5, 3, 1]
ผลลัพธ์
[7, 6, 5, 4, 3]
[9, 7, 5, 3, 1]

การตัดช่วงสตริง ลิสต์ และทูเพิล

รูปแบบ [start:stop:step] เดียวกันนี้ใช้ได้กับลำดับข้อมูลทุกชนิด สิ่งเดียวที่ต่างคือสิ่งที่ได้กลับมา: ตัดช่วงลิสต์ได้ลิสต์ ตัดช่วงสตริงได้สตริง และตัดช่วงทูเพิลได้ทูเพิล

การตัดช่วงคงชนิดข้อมูลเดิมไว้
# Slicing a string -> string
name = 'Alexander'
print(name[0:4]) # Alex
print(type(name[0:4])) # <class 'str'>
# Slicing a list -> list
scores = [90, 85, 77, 92, 88]
print(scores[1:4]) # [85, 77, 92]
# Slicing a tuple -> tuple
point = (10, 20, 30, 40, 50)
print(point[::2]) # (10, 30, 50)
ผลลัพธ์
Alex
<class 'str'>
[85, 77, 92]
(10, 30, 50)

รูปแบบการตัดช่วงที่นักพัฒนา Python ทุกคนควรรู้

นี่คือรูปแบบการตัดช่วงที่คุณจะเห็นและใช้บ่อยที่สุด ใช้เป็นตารางอ้างอิงฉบับย่อได้เลย

รูปแบบการตัดช่วงสำคัญ 6 แบบ
data = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# First N items
print(data[:3]) # ['a', 'b', 'c']
# Last N items
print(data[-3:]) # ['e', 'f', 'g']
# Remove first item
print(data[1:]) # ['b', 'c', 'd', 'e', 'f', 'g']
# Remove last item
print(data[:-1]) # ['a', 'b', 'c', 'd', 'e', 'f']
# Middle items (remove first and last)
print(data[1:-1]) # ['b', 'c', 'd', 'e', 'f']
# Reverse the whole thing
print(data[::-1]) # ['g', 'f', 'e', 'd', 'c', 'b', 'a']
ผลลัพธ์
['a', 'b', 'c']
['e', 'f', 'g']
['b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f']
['b', 'c', 'd', 'e', 'f']
['g', 'f', 'e', 'd', 'c', 'b', 'a']

คุณยังใช้การตัดช่วงทางซ้ายของการกำหนดค่าเพื่อแทนที่บางส่วนของลิสต์ได้ด้วย เรียกว่า การกำหนดค่าแบบตัดช่วง (slice assignment)

การกำหนดค่าแบบตัดช่วง (ใช้ได้กับลิสต์เท่านั้น)
colors = ['red', 'green', 'blue', 'yellow', 'purple']
# Replace items at index 1 and 2
colors[1:3] = ['lime', 'sky']
print(colors) # ['red', 'lime', 'sky', 'yellow', 'purple']
# You can even replace with a different number of items
colors[1:3] = ['orange']
print(colors) # ['red', 'orange', 'yellow', 'purple']
ผลลัพธ์
['red', 'lime', 'sky', 'yellow', 'purple']
['red', 'orange', 'yellow', 'purple']

แบบฝึกหัด

ดึงสมาชิกตรงกลาง
เขียนโค้ด

จากลิสต์ animals ใช้การตัดช่วงเพื่อแสดงเฉพาะสมาชิกสามตัวตรงกลาง: ['cat', 'dog', 'elephant']

animals = ['ant', 'bear', 'cat', 'dog', 'elephant', 'fox', 'giraffe']
# Print the middle three items using slicing
ทายผลการตัดช่วง
ทายผลลัพธ์

โค้ดนี้แสดงผลอะไร คิดให้ดีเรื่องดัชนีลบ

word = 'programming'
print(word[-4:])

เขียนคำสั่ง print() ที่แสดงผลออกมาเหมือนกันทุกตัวอักษร

# Predict the output and write the matching print statement
print("?")
ดึงสมาชิกที่ดัชนีเป็นเลขคู่
เขียนโค้ด

จากลิสต์ letters ใช้การตัดช่วงพร้อม step เพื่อแสดงเฉพาะสมาชิกที่ดัชนีเป็นเลขคู่ (0, 2, 4, 6) ผลลัพธ์ควรเป็น ['a', 'c', 'e', 'g']

letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
# Print items at even indices using slicing
กลับลำดับคำ
เขียนโค้ด

ใช้การตัดช่วงเพื่อกลับลำดับสตริง word แล้วแสดงผล ผลลัพธ์ควรเป็น nohtyp

word = 'python'
# Reverse the word using slicing and print it
แก้บั๊กการตัดช่วง
แก้บั๊ก

โค้ดนี้พยายามดึงสมาชิกสามตัวสุดท้ายจากลิสต์ แต่ใช้การตัดช่วงผิด แก้บั๊กให้แสดงผล ['date', 'elderberry', 'fig']

fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry', 'fig']
# Bug: this doesn't get the last three items
last_three = fruits[3:0]
print(last_three)
ตัวตรวจพาลินโดรม
เขียนโค้ด

เขียนฟังก์ชันชื่อ is_palindrome(text) ที่คืนค่า True ถ้าข้อความอ่านจากหน้าไปหลังและจากหลังไปหน้าได้เหมือนกัน และคืน False ถ้าไม่ใช่ ใช้การตัดช่วงเพื่อกลับลำดับสตริง และแปลงข้อความเป็นตัวพิมพ์เล็กก่อน เพื่อให้การตรวจไม่สนใจว่าเป็นตัวพิมพ์เล็กหรือใหญ่

ทดสอบด้วยการเรียกเหล่านี้:

print(is_palindrome('racecar'))
print(is_palindrome('Python'))
print(is_palindrome('Madam'))
def is_palindrome(text):
# Convert to lowercase and check if it equals its reverse
pass
print(is_palindrome('racecar'))
print(is_palindrome('Python'))
print(is_palindrome('Madam'))

บทเรียนที่เกี่ยวข้อง

บทเรียนนี้มีประโยชน์หรือไม่