การแยกและแทนที่องค์ประกอบที่ตรงตามเงื่อนไขของรายการ (อาร์เรย์) ของสตริงในPython

ธุรกิจ

ในการสร้างรายการใหม่จากรายการ (อาร์เรย์) ที่มีองค์ประกอบเป็นสตริง โดยแยกเฉพาะองค์ประกอบของสตริงที่ตรงตามเงื่อนไขบางประการ หรือโดยการแทนที่ การแปลง ฯลฯ ให้ใช้รายการความเข้าใจ

หลังจากคำอธิบายสั้นๆ เกี่ยวกับความเข้าใจรายการ เนื้อหาต่อไปนี้จะอธิบายด้วยโค้ดตัวอย่าง

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

โปรดทราบว่ารายการสามารถจัดเก็บข้อมูลประเภทต่างๆ และแตกต่างจากอาร์เรย์โดยสิ้นเชิง หากคุณต้องการจัดการอาร์เรย์ในกระบวนการที่ต้องการขนาดหน่วยความจำและที่อยู่หน่วยความจำ หรือการประมวลผลตัวเลขของข้อมูลขนาดใหญ่ ให้ใช้อาร์เรย์ (ไลบรารีมาตรฐาน) หรือ NumPy

สัญกรณ์รวมรายการ

เมื่อสร้างรายการใหม่จากรายการ ความเข้าใจของรายการจะเขียนได้ง่ายกว่าการวนซ้ำ

[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']
Copied title and URL