ฉันจะรับซับสตริงของสตริงใน Python ได้อย่างไร


2144

มีวิธีการ substring สตริงใน Python เพื่อรับสายใหม่จากตัวละครที่สามไปยังจุดสิ้นสุดของสตริงหรือไม่

อาจจะชอบmyString[2:end]?

ถ้าออกจากส่วนที่สองหมายถึง 'จนจบ' และถ้าคุณออกจากส่วนแรกมันจะเริ่มจากจุดเริ่มต้นหรือไม่?


1
อันนี้มีคำอธิบายที่ชัดเจนpythoncentral.io/cutting-and-slicing-strings-in-python
mario ruiz

คำตอบ:


3178
>>> x = "Hello World!"
>>> x[2:]
'llo World!'
>>> x[:2]
'He'
>>> x[:-2]
'Hello Worl'
>>> x[-2:]
'd!'
>>> x[2:-2]
'llo Worl'

Python เรียกแนวคิดนี้ว่า "slicing" และมันทำงานได้มากกว่าแค่สาย ลองดูที่นี่สำหรับคำแนะนำที่ครอบคลุม


401

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

some_string[::-1]

หรือเลือกตัวละครอื่นจะเป็น:

"H-e-l-l-o- -W-o-r-l-d"[::2] # outputs "Hello World"

ความสามารถในการก้าวไปข้างหน้าและถอยหลังผ่านสตริงรักษาความสอดคล้องกับความสามารถในการจัดเรียงอาร์เรย์ตั้งแต่เริ่มต้นหรือสิ้นสุด


21
@tahmed เกี่ยวข้องกับคำถามอย่างแน่นอน ถ้าคุณต้องการซับสตริงโดยเลือกอักขระสำรองจากสตริง นั่นจะเป็น my_string [:: 2]
Endophage

ฉันคิดว่าคุณน่าจะพูดถึงพารามิเตอร์ที่สามในการแบ่งส่วน ต้องได้อักขระทุกตัวจากสายอักขระอาจเป็นกรณีการใช้งานที่สำคัญที่ไหนสักแห่ง แต่ฉันไม่เคยทำมาก่อน ไม่ใช่ว่ามีอะไรผิดปกติกับที่ต้องการอวดสิ่งที่คุณรู้ - อะไรคือจุดที่รู้สิ่งต่าง ๆ ถ้าคุณไม่สามารถทำเช่นนั้นได้ :) แต่กรณีที่เกี่ยวข้องกับคำถามนั้นเกินจริง
John Lockwood

1
แน่นอนว่าตัวอย่างที่เฉพาะเจาะจงในการเลือกอักขระอื่นอาจไม่เกี่ยวข้องกับคำถาม แต่การเข้าใจว่ามีพารามิเตอร์ตัวที่ 3 ในการแบ่งส่วนอย่างมากนั้นมีความเกี่ยวข้องและตัวอย่างง่าย ๆ ใช้เพื่ออธิบายวิธีการทำงาน ชุมชน Python มีประวัติที่ดีในการให้ความรู้แก่สมาชิกใหม่ด้วยวิธีที่เป็นมิตร :-)
Endophage

127

Substr () ปกติ (เช่น PHP และ Perl) ทำงานในลักษณะนี้:

s = Substr(s, beginning, LENGTH)

ดังนั้นพารามิเตอร์และbeginningLENGTH

แต่พฤติกรรมของไพ ธ อนนั้นแตกต่างกัน คาดว่าจะเริ่มต้นและอีกครั้งหลังจาก END (!) เป็นการยากที่จะสังเกตเห็นโดยผู้เริ่มต้น ดังนั้นการแทนที่ที่ถูกต้องสำหรับ Substr (s, start, LENGTH) คือ

s = s[ beginning : beginning + LENGTH]

76
ผู้เริ่มต้นควรเรียนรู้วิธีการไพ ธ อนเมื่อย้ายไปยังงูหลามไม่ยึดติดกับนิสัยภาษาอื่น
Nicu Surdu

3
และเพื่อความสมบูรณ์ Java นั้นก็เหมือนกับ Python ที่เมธอด String.substring () นั้นเริ่มต้นและจบไปแล้ว อันนี้ยากสำหรับฉันฉันคิดว่ามันมีความยาวเหมือนฟังก์ชันย่อยอื่น ๆ ในโลก
PhilHibbs

4
A (อาจ) วิธี pythonic มากขึ้นที่จะทำคือs[beginning:][:length]
victortv

2
ในฐานะคนที่เริ่มต้นด้วย Python แทนที่จะเป็น [คำที่สกปรก] - ภาษาเช่น PHP ฉันคิดว่า Python นั้นง่ายและใช้งานง่ายกว่าด้วยสตริง [เริ่มต้น: สิ้นสุด] ความยาวโดยทั่วไปไม่เกี่ยวข้องกัน
Gloweye

60

วิธีทั่วไปในการบรรลุเป้าหมายนี้คือการแบ่งส่วนสตริง

MyString[a:b] ให้ซับสตริงจากดัชนี a ถึง (b - 1)


23

ตัวอย่างหนึ่งดูเหมือนว่าจะหายไปที่นี่: สำเนา (ตื้น) เต็ม

>>> x = "Hello World!"
>>> x
'Hello World!'
>>> x[:]
'Hello World!'
>>> x==x[:]
True
>>>

นี้เป็นสำนวนที่พบบ่อยสำหรับการสร้างสำเนาของประเภทลำดับ [:](ไม่ใช่ของสตริงฝึกงาน) สำเนาตื้นรายการดูงูหลามไวยากรณ์รายการชิ้นที่ใช้สำหรับการไม่มีเหตุผลที่ชัดเจน


12
สิ่งนี้แทบไม่เกี่ยวกับคำถามเกี่ยวกับสตริงย่อย ไม่ได้ใช้กับสตริง กำลังพูด stringA = stringB ก็พอ ...
Nicu Surdu

2
สำเนาเต็ม [:] สร้างสำเนาใหม่ใช้ไวยากรณ์ส่วนและอ่านเป็น "สตริงย่อยตั้งแต่ต้นจนจบ"
gimel

2
จุดคืออะไรตั้งแต่สตริงไม่เปลี่ยนรูป? a=bควรจะเพียงพอ
bfontaine

1
@gimel: ที่จริงแล้ว[:]ในประเภทที่ไม่เปลี่ยนรูปไม่ได้ทำสำเนาเลย ในขณะที่mysequence[:]ส่วนใหญ่จะเป็นอันตรายเมื่อmysequenceเป็นประเภทไม่เปลี่ยนรูปเหมือนstr, tuple, bytes(Py3) หรือunicode(Py2) a = b[:]เทียบเท่ากับa = bก็แค่เสียเวลาน้อยเยี่ยงอย่างรหัสไบต์หั่นซึ่งตอบสนองวัตถุโดยการกลับตัวเองตั้งแต่มันไม่มีจุดหมายที่จะสำเนาตื้นเมื่อ นอกเหนือจากการทดสอบตัวตนของวัตถุแล้วมันก็เท่ากับกลับไปอ้างอิงกับตัวตนที่ไม่เปลี่ยนรูปอีกคนหนึ่ง
ShadowRanger

3
ความพยายามที่จะรวมถึงการวิพากษ์วิจารณ์อื่น ๆ ของคำตอบนี้: ใน Python, สตริงจะไม่เปลี่ยนรูปจึงมีเหตุผลที่จะทำสำเนาของสตริงไม่มี - ดังนั้นไม่ทำสำเนาที่ทั้งหมด:s[:] s = 'abc'; s0 = s[:]; assert s is s0ใช่มันเป็นวิธีที่ใช้สำนวนเพื่อคัดลอกรายการใน Python จนกว่ารายการจะได้รับlist.copyแต่ชิ้นส่วนที่ไม่เปลี่ยนรูปแบบเต็มรูปแบบไม่มีเหตุผลที่จะทำสำเนาเพราะมันไม่สามารถเปลี่ยนแปลงได้ดังนั้นอาจมีเพียงหนึ่งในหน่วยความจำและ เราไม่ควรเสียเวลาคัดลอก เนื่องจากคำตอบนี้ผิดและไม่ได้ตอบคำถามด้วย - ควรลบไหม
Aaron Hall

18

มีวิธีการ substring สตริงใน Python เพื่อรับสายใหม่จากตัวอักษรที่ 3 ถึงจุดสิ้นสุดของสตริงหรือไม่

อาจจะชอบmyString[2:end]?

ใช่มันใช้งานได้จริงถ้าคุณมอบหมายหรือผูกชื่อendให้กับซิงเกิลคงที่None:

>>> end = None
>>> myString = '1234567890'
>>> myString[2:end]
'34567890'

สัญกรณ์ Slice มีอาร์กิวเมนต์ที่สำคัญ 3 ข้อ:

  • เริ่มต้น
  • หยุด
  • ขั้นตอน

ค่าเริ่มต้นของพวกเขาเมื่อไม่ได้รับคือNone- แต่เราสามารถส่งต่อได้อย่างชัดเจน:

>>> stop = step = None
>>> start = 2
>>> myString[start:stop:step]
'34567890'

หากออกจากส่วนที่สองหมายถึง 'จนจบ' ถ้าคุณออกจากส่วนแรกมันจะเริ่มจากจุดเริ่มต้นหรือไม่?

ใช่เช่น:

>>> start = None
>>> stop = 2
>>> myString[start:stop:step]
'12'

โปรดทราบว่าเรารวมการเริ่มในส่วนย่อย แต่เราไปถึงเท่านั้นและไม่รวมถึงหยุด

เมื่อขั้นตอนคือNoneโดยค่าเริ่มต้นชิ้นใช้1สำหรับขั้นตอน หากคุณก้าวด้วยจำนวนเต็มลบ Python จะฉลาดพอที่จะเปลี่ยนจากต้นจนจบ

>>> myString[::-1]
'0987654321'

ฉันอธิบายสัญกรณ์ชิ้นอย่างละเอียดในคำตอบของฉันเพื่ออธิบายสัญกรณ์ชิ้น


8

คุณเข้าใจถูกต้องแล้วยกเว้น "จบ" มันเรียกว่าสัญกรณ์ชิ้น ตัวอย่างของคุณควรอ่าน:

new_sub_string = myString[2:]

หากคุณเว้นพารามิเตอร์ตัวที่สองมันจะเป็นการสิ้นสุดของสตริงโดยปริยาย


6

ฉันต้องการเพิ่มสองจุดในการสนทนา:

  1. คุณสามารถใช้Noneแทนในพื้นที่ว่างเพื่อระบุ "ตั้งแต่เริ่มต้น" หรือ "ถึงท้าย":

    'abcde'[2:None] == 'abcde'[2:] == 'cde'

    สิ่งนี้มีประโยชน์อย่างยิ่งในฟังก์ชั่นซึ่งคุณไม่สามารถระบุพื้นที่ว่างเป็นอาร์กิวเมนต์ได้:

    def substring(s, start, end):
        """Remove `start` characters from the beginning and `end` 
        characters from the end of string `s`.
    
        Examples
        --------
        >>> substring('abcde', 0, 3)
        'abc'
        >>> substring('abcde', 1, None)
        'bcde'
        """
        return s[start:end]
  2. Python มีวัตถุชิ้น :

    idx = slice(2, None)
    'abcde'[idx] == 'abcde'[2:] == 'cde'

6

หาก myString มีเลขที่บัญชีที่เริ่มต้นที่ชดเชยที่ 6 และมีความยาว 9 acct = myString[6:][:9]แล้วคุณสามารถดึงเลขที่บัญชีด้วยวิธีนี้:

หาก OP ยอมรับว่าพวกเขาอาจต้องการลองแบบทดลอง

myString[2:][:999999]

ใช้งานได้ - ไม่มีข้อผิดพลาดเกิดขึ้นและไม่มีการตั้งค่า 'การเว้นช่องว่างสตริง' เริ่มต้น


1
ฉันคิดว่าถ้าคุณต้องการใช้วิธีนี้myString[offset:][:length]ในกรณีของ OP คุณสามารถใช้myString[offset:][:]
victortv

1
@VictorVal คำตอบสำหรับผู้ที่ (เช่นฉัน) ที่ได้เรียนรู้ภาษา Python เป็นภาษาโปรแกรมที่ 2 (3, 4, ... ) และต้องการ 'syntax hooks' ที่คุ้นเคยเพื่อเข้าถึงภาษา ผู้เชี่ยวชาญด้านภาษามักจะมองว่าคำตอบของฉันค่อนข้างโง่
CopyPasteIt

คำตอบเช่นนี้ถูกตั้งค่าสถานะเพื่อลบหรือไม่ คำตอบอื่น ๆ อธิบายวิธีแก้ปัญหาที่คล้ายกันดีกว่ามากและการเห็นสิ่งนี้ทำให้ฉันเกาหัวและค้นหางูหลามสักสองสามนาทีก่อนที่จะรู้ตัวว่ามันเป็นเพียงคำตอบประเภทนั้น
Sebi

3

บางทีฉันอาจจะพลาด แต่ฉันไม่สามารถหาคำตอบที่สมบูรณ์ในหน้านี้กับคำถามเดิมเนื่องจากตัวแปรไม่ได้กล่าวถึงต่อไปที่นี่ ดังนั้นฉันจึงต้องค้นหาต่อไป

เนื่องจากฉันยังไม่ได้รับอนุญาตให้แสดงความคิดเห็นให้ฉันเพิ่มข้อสรุปของฉันที่นี่ ฉันแน่ใจว่าฉันไม่ใช่คนเดียวที่สนใจในการเข้าถึงหน้านี้:

 >>>myString = 'Hello World'
 >>>end = 5

 >>>myString[2:end]
 'llo'

ถ้าคุณออกจากส่วนแรกคุณจะได้รับ

 >>>myString[:end]
 'Hello' 

และถ้าคุณปล่อยให้: ตรงกลางเช่นกันคุณจะได้สตริงย่อยที่ง่ายที่สุดซึ่งจะเป็นอักขระตัวที่ 5 (นับจากเริ่มต้นด้วย 0 ดังนั้นมันจะว่างเปล่าในกรณีนี้):

 >>>myString[end]
 ' '

1

ดีฉันมีสถานการณ์ที่ฉันต้องการที่จะแปล PHP substr(string, beginning, LENGTH)สคริปต์ให้งูหลามและมันมีประเพณีหลาย
ถ้าฉันเลือก Python string[beginning:end]ฉันจะต้องคำนวณดัชนีปลายจำนวนมากดังนั้นวิธีที่ง่ายกว่าคือใช้string[beginning:][:length]มันช่วยฉันได้หลายปัญหา


0

การใช้ดัชนี hardcoded นั้นสามารถทำให้เกิดความยุ่งเหยิงได้

เพื่อหลีกเลี่ยงปัญหานั้น Python นำเสนอวัตถุในslice()ตัว

string = "my company has 1000$ on profit, but I lost 500$ gambling."

ถ้าเราอยากรู้ว่าฉันเหลือเงินเท่าไหร่

วิธีการแก้ปัญหาปกติ:

final = int(string[15:19]) - int(string[43:46])
print(final)
>>>500

ใช้ชิ้น:

EARNINGS = slice(15, 19)
LOSSES = slice(43, 46)
final = int(string[EARNINGS]) - int(string[LOSSES])
print(final)
>>>500

การใช้ชิ้นงานคุณจะสามารถอ่านได้


5
บางทีนี่อาจไม่ใช่ตัวอย่างที่ดีที่สุดเนื่องจากดัชนีฮาร์ดโค้ดยังคงอยู่และความสามารถในการอ่านนั้นมาจากตัวแปรกลางซึ่งคุณสามารถใช้ในตัวอย่างแรก
ASalazar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.