ในการสร้างรายการใหม่จากรายการ (อาร์เรย์) ที่มีองค์ประกอบเป็นสตริง โดยแยกเฉพาะองค์ประกอบของสตริงที่ตรงตามเงื่อนไขบางประการ หรือโดยการแทนที่ การแปลง ฯลฯ ให้ใช้รายการความเข้าใจ
หลังจากคำอธิบายสั้นๆ เกี่ยวกับความเข้าใจรายการ เนื้อหาต่อไปนี้จะอธิบายด้วยโค้ดตัวอย่าง
- การแยกขึ้นอยู่กับว่ารวมสตริงเฉพาะหรือไม่ (การจับคู่บางส่วน)
- แทนที่สตริงเฉพาะ
- แยกโดยการขึ้นต้นหรือไม่ขึ้นต้นด้วยสตริงเฉพาะ
- แยกโดยการลงท้ายหรือไม่ลงท้ายด้วยสตริงเฉพาะ
- ตัดสินและแยกเป็นกรณีๆ ไป
- แปลงตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
- กำหนดว่าจะใช้ตัวอักษรหรือตัวเลขและแยกออก
- หลายเงื่อนไข
- (คอมพิวเตอร์) นิพจน์ทั่วไป
โปรดทราบว่ารายการสามารถจัดเก็บข้อมูลประเภทต่างๆ และแตกต่างจากอาร์เรย์โดยสิ้นเชิง หากคุณต้องการจัดการอาร์เรย์ในกระบวนการที่ต้องการขนาดหน่วยความจำและที่อยู่หน่วยความจำ หรือการประมวลผลตัวเลขของข้อมูลขนาดใหญ่ ให้ใช้อาร์เรย์ (ไลบรารีมาตรฐาน) หรือ NumPy
- สัญกรณ์รวมรายการ
- มีสตริงเฉพาะ (การจับคู่บางส่วน) \ ไม่มี:in
- แทนที่สตริงเฉพาะ
- เริ่มต้นด้วยสตริงเฉพาะ \ ไม่เริ่ม:startswith()
- ลงท้ายด้วยสตริงอักขระเฉพาะ \ not end:endswith()
- ตัดสินและแยกเป็นกรณีๆ ไป
- แปลงตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
- กำหนดว่าจะใช้ตัวอักษรหรือตัวเลขและแยกออก
- หลายเงื่อนไข
- (คอมพิวเตอร์) นิพจน์ทั่วไป
สัญกรณ์รวมรายการ
เมื่อสร้างรายการใหม่จากรายการ ความเข้าใจของรายการจะเขียนได้ง่ายกว่าการวนซ้ำ
- ที่เกี่ยวข้อง:วิธีใช้ Python list comprehensions
[expression for any variable name in iterable object if conditional expression]
หากองค์ประกอบถูกเลือกโดยนิพจน์เงื่อนไขเท่านั้น องค์ประกอบนั้นจะไม่ถูกประมวลผลโดยนิพจน์ ดังนั้นจะใช้รูปแบบต่อไปนี้
[variable name for variable name in original list if conditional expression]
ถ้านิพจน์เงื่อนไข if ถูกสร้างเป็นนิพจน์เงื่อนไข if นั้นจะกลายเป็นการปฏิเสธ และองค์ประกอบที่ไม่เป็นไปตามนิพจน์เงื่อนไขสามารถแยกออกมาได้
มีสตริงเฉพาะ (การจับคู่บางส่วน) \ ไม่มี:in
ใน “สตริงที่ระบุในสตริงดั้งเดิม” ส่งคืน True หากสตริงดั้งเดิมมีสตริงที่ระบุ นี่คือนิพจน์เงื่อนไข
การปฏิเสธ in เสร็จสิ้นด้วย not in
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']
l_in_not = [s for s in l if 'XXX' not in s]
print(l_in_not)
# ['three999aaa', '000111222']
แทนที่สตริงเฉพาะ
หากคุณต้องการแทนที่สตริงขององค์ประกอบรายการ ให้ใช้เมธอดสตริง replace() สำหรับแต่ละองค์ประกอบในสัญกรณ์ความเข้าใจรายการ
หากไม่มีสตริงที่จะแทนที่ ไม่จำเป็นต้องเลือกองค์ประกอบในนิพจน์เงื่อนไข if เพราะจะไม่ถูกเปลี่ยนโดยใช้การแทนที่ ()
l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']
หากคุณต้องการแทนที่องค์ประกอบทั้งหมดที่มีสตริงเฉพาะ ให้แยกด้วย in และประมวลผลด้วยตัวดำเนินการ ternary ตัวดำเนินการ ternary ถูกเขียนในรูปแบบต่อไปนี้True Value if Conditional Expression else False Value
เป็นเรื่องปกติถ้าส่วนนิพจน์ของสัญกรณ์ความเข้าใจรายการเป็นตัวดำเนินการแบบไตรภาค
l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']
ต่อไปนี้เป็นบทสรุปของผลลัพธ์ในวงเล็บ หากคุณไม่คุ้นเคยกับการใช้วงเล็บ อาจทำให้เข้าใจและหลีกเลี่ยงข้อผิดพลาดได้ง่ายขึ้น ตามหลักไวยากรณ์ ไม่มีปัญหาแม้ว่าคุณจะเขียนวงเล็บก็ตาม
[('ZZZ' if ('XXX' in s) else s) for s in l]
การใช้ in เป็นเงื่อนไขทำให้เกิดความสับสนกับสัญกรณ์ความเข้าใจรายการ แต่ไม่ยากหากคุณทราบรูปแบบวากยสัมพันธ์ของสัญกรณ์ความเข้าใจรายการและตัวดำเนินการแบบไตรภาค
เริ่มต้นด้วยสตริงเฉพาะ \ ไม่เริ่ม:startswith()
วิธีการสตริง startwith() คืนค่า จริง หากสตริงเริ่มต้นด้วยสตริงที่ระบุในอาร์กิวเมนต์
l_start = [s for s in l if s.startswith('t')]
print(l_start)
# ['twoXXXbbb', 'three999aaa']
l_start_not = [s for s in l if not s.startswith('t')]
print(l_start_not)
# ['oneXXXaaa', '000111222']
ลงท้ายด้วยสตริงอักขระเฉพาะ \ not end:endswith()
วิธีสตริงที่สิ้นสุดด้วย () คืนค่า จริง หากสตริงลงท้ายด้วยสตริงที่ระบุในอาร์กิวเมนต์
l_end = [s for s in l if s.endswith('aaa')]
print(l_end)
# ['oneXXXaaa', 'three999aaa']
l_end_not = [s for s in l if not s.endswith('aaa')]
print(l_end_not)
# ['twoXXXbbb', '000111222']
ตัดสินและแยกเป็นกรณีๆ ไป
สามารถใช้เมธอดสตริง isupper(),islower() เพื่อตรวจสอบว่าสตริงเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กทั้งหมด
l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']
แปลงตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
หากคุณต้องการแปลงอักขระทั้งหมดเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก ให้ใช้วิธีสตริง upper() และ lower() วิธีอื่นๆ ได้แก่ ตัวพิมพ์ใหญ่ () ซึ่งใช้เฉพาะอักษรตัวแรก และ swapcase () ซึ่งจะสลับอักษรตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก
ในตัวอย่างการแทนที่ด้านบน ให้ใช้ตัวดำเนินการ ternary หากคุณต้องการประมวลผลเฉพาะองค์ประกอบที่ตรงตามเงื่อนไข
l_upper_all = [s.upper() for s in l]
print(l_upper_all)
# ['ONEXXXAAA', 'TWOXXXBBB', 'THREE999AAA', '000111222']
l_lower_to_upper = [s.upper() if s.islower() else s for s in l]
print(l_lower_to_upper)
# ['oneXXXaaa', 'twoXXXbbb', 'THREE999AAA', '000111222']
กำหนดว่าจะใช้ตัวอักษรหรือตัวเลขและแยกออก
สามารถใช้เมธอดสตริง isalpha() และ isnumeric() เพื่อกำหนดว่าสตริงเป็นตัวอักษร ตัวเลข ฯลฯ ทั้งหมดหรือไม่
l_isalpha = [s for s in l if s.isalpha()]
print(l_isalpha)
# ['oneXXXaaa', 'twoXXXbbb']
l_isnumeric = [s for s in l if s.isnumeric()]
print(l_isnumeric)
# ['000111222']
หลายเงื่อนไข
ส่วนนิพจน์เงื่อนไขของการเข้าใจรายการสามารถมีได้หลายเงื่อนไข สามารถใช้เงื่อนไข “ไม่” เชิงลบได้เช่นกัน
เมื่อใช้นิพจน์เงื่อนไขตั้งแต่สามรายการขึ้นไป จะปลอดภัยกว่าที่จะใส่แต่ละกลุ่มในวงเล็บ () เนื่องจากผลลัพธ์จะแตกต่างกันไปขึ้นอยู่กับลำดับ
l_multi = [s for s in l if s.isalpha() and not s.startswith('t')]
print(l_multi)
# ['oneXXXaaa']
l_multi_or = [s for s in l if (s.isalpha() and not s.startswith('t')) or ('bbb' in s)]
print(l_multi_or)
# ['oneXXXaaa', 'twoXXXbbb']
(คอมพิวเตอร์) นิพจน์ทั่วไป
นิพจน์ทั่วไปช่วยให้การประมวลผลมีความยืดหยุ่นสูง
วัตถุที่ตรงกันที่ส่งคืนโดย re.match() เมื่อจับคู่จะถูกกำหนดให้เป็นจริงเสมอเมื่อประเมินด้วยนิพจน์เงื่อนไข หากไม่ตรงกัน จะส่งกลับ None ซึ่งเป็นเท็จในนิพจน์เงื่อนไข ดังนั้น หากคุณต้องการแยกเฉพาะองค์ประกอบที่ตรงกับนิพจน์ทั่วไป เพียงใช้ re.match() กับส่วนนิพจน์เงื่อนไขของนิพจน์ความเข้าใจรายการเหมือนเมื่อก่อน
import re
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_re_match = [s for s in l if re.match('.*XXX.*', s)]
print(l_re_match)
# ['oneXXXaaa', 'twoXXXbbb']
re.sub() ซึ่งแทนที่ส่วนที่ตรงกันของนิพจน์ทั่วไปก็มีประโยชน์เช่นกัน หากต้องการแยกและแทนที่เฉพาะองค์ประกอบที่ตรงกัน เพียงเพิ่ม “ถ้านิพจน์เงื่อนไข”
l_re_sub_all = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l]
print(l_re_sub_all)
# ['aaa---one', 'bbb---two', 'three999aaa', '000111222']
l_re_sub = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l if re.match('.*XXX.*', s)]
print(l_re_sub)
# ['aaa---one', 'bbb---two']