เหตุใดการแบ่งส่วนย่อยด้วยดัชนีจึงไม่อยู่ในช่วง


90

เหตุใดจึงไม่'example'[999:9999]เกิดข้อผิดพลาด เนื่องจาก'example'[9]ไม่สิ่งที่เป็นแรงจูงใจที่อยู่เบื้องหลังมันได้หรือไม่

จากพฤติกรรมนี้ฉันสามารถสันนิษฐานได้ว่า'example'[3]โดยพื้นฐานแล้ว / ภายในไม่เหมือนกับ'example'[3:4]แม้ว่าทั้งสองจะให้ผลลัพธ์ใน'm'สตริงเดียวกัน


17
[999:9999]ไม่ใช่ดัชนี แต่เป็นชิ้นส่วนและมีความหมายที่แตกต่างกัน จากคำนำ python: "ดัชนีชิ้นส่วนที่เสื่อมสภาพได้รับการจัดการอย่างสง่างาม: ดัชนีที่ใหญ่เกินไปจะถูกแทนที่ด้วยขนาดสตริงขอบเขตบนที่เล็กกว่าขอบเขตล่างจะส่งคืนสตริงว่าง"
Wooble

2
@ Wooble นั่นคือคำตอบที่แท้จริง
jondavidjohn

2
@ Wooble แล้วรู้มั้ยว่าทำไมถึงเป็นแบบนี้? ขอบคุณสำหรับคำชี้แจง
ijverig

ทำไม? คุณต้องถาม Guido แต่ฉันคิดว่ามันเป็นการดีที่จะถือว่าชิ้นส่วนเป็นลำดับประเภทเดียวกับลำดับดั้งเดิมเสมอตัวฉันเอง
Wooble

1
@Lapinot ใช่ฉันเขียนโค้ดที่ขึ้นอยู่กับพฤติกรรมนี้ น่าเสียดายที่ฉันจำรหัสที่แน่นอนไม่ได้จึงไม่สามารถบอกคุณได้ว่าทำไม อาจเกี่ยวข้องกับสตริงย่อย การหาสตริงว่างอาจเป็นสิ่งที่คุณต้องการในบางครั้ง
Mark Ransom

คำตอบ:


69

ถูกต้อง! 'example'[3:4]และ'example'[3]มีความแตกต่างกันโดยพื้นฐานและการแบ่งส่วนนอกขอบเขตของลำดับ (อย่างน้อยสำหรับบิวด์อิน) จะไม่ทำให้เกิดข้อผิดพลาด

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

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

>>> [0, 1, 2, 3, 4, 5][3]
3
>>> [0, 1, 2, 3, 4, 5][3:4]
[3]

นี่คือความแตกต่างที่ชัดเจน ในกรณีของสตริงผลลัพธ์จะเหมือนกันเนื่องจากใน Python ไม่มีสิ่งที่เรียกว่าอักขระแต่ละตัวนอกสตริง อักขระเดี่ยวเป็นเพียงสตริง 1 อักขระ

(สำหรับความหมายที่แน่นอนของการหั่นนอกช่วงของลำดับโปรดดูคำตอบของ mgilson )


1
ดัชนีที่อยู่นอกช่วงอาจส่งคืนNoneแทนที่จะเกิดข้อผิดพลาดนั่นคือหลักการปกติของ Python เมื่อคุณไม่มีอะไรจะกลับ
Mark Ransom

8
@MarkRansom จริงค่ะ; แต่การกลับมาNoneในกรณีนี้จะทำให้ยากที่จะบอกระหว่างดัชนีนอกขอบเขตกับNoneค่าภายในรายการ แต่แม้ว่าจะมีวิธีแก้ปัญหาสำหรับสิ่งนั้น แต่ก็ยังคงชัดเจนสำหรับฉันว่าการส่งคืนลำดับที่ว่างเปล่าเป็นสิ่งที่ถูกต้องเมื่อได้รับชิ้นส่วนที่ไม่อยู่ในขอบเขต มันคล้ายกับการรวมกันของสองชุดที่ไม่ปะติดปะต่อกัน
ส่ง

เพื่อความชัดเจนฉันไม่ได้บอกว่าคุณผิด ฉันเห็นประเด็นของคุณเกี่ยวกับNoneค่าในรายการ
Mark Ransom

1
@MarkRansom ฉันรู้ - ขอโทษถ้าฉันฟังดูปกป้อง จริงๆฉันแค่ต้องการข้ออ้างเพื่ออ้างถึงทฤษฎีเซต :)
ส่ง

4
แย่จังยกเว้นฉันพูดว่า "union" แทนที่จะเป็น "ทางแยก"
ส่ง

33

เพื่อประโยชน์ในการเพิ่มคำตอบที่ชี้ไปยังส่วนที่มีประสิทธิภาพในเอกสารประกอบ :

ได้รับการแสดงออกชิ้นเช่นs[i:j:k],

ชิ้นของsจากฉันไปเจด้วยขั้นตอนkถูกกำหนดให้เป็นลำดับของรายการที่มีดัชนีดังกล่าวว่าx = i + n*k 0 <= n < (j-i)/kในคำอื่น ๆ ที่มีดัชนีi, i+k, i+2*k, i+3*kและอื่น ๆ หยุดเมื่อเจจะมาถึง ( แต่ไม่รวมถึงเจ ) เมื่อkเป็นบวกiและjจะลดลงเป็นlen(s)ถ้ามากกว่า

ถ้าคุณเขียนs[999:9999]python จะกลับมาs[len(s):len(s)]ตั้งแต่นั้นlen(s) < 999และขั้นตอนของคุณเป็นค่าบวก ( 1- ค่าเริ่มต้น)


สันนิษฐานว่าเมื่อใดkเป็นบวกiและjเพิ่มขึ้นเป็น-len(s)เมื่อน้อยกว่า? เช่นs = 'bac'; s[-100:2] == s[-len(s):2]
Chris_Rands

@Chris_Rands เมื่อkใดที่เป็นค่าบวก Python จะปรับขนาดiและjเพื่อให้พอดีกับขอบเขตของลำดับ ในตัวอย่างของคุณs[-100:2] == s[0:2]( == s[-len(s):2]โดยวิธีการ) ในทำนองเดียวกันs[-100:100] == s[0:2].
tylerc0816

ดีขอบคุณ นี่เป็นการตอบสนองที่ดีกว่าสำหรับความคิดเห็นของ @ speedplane ด้านบน
ส่ง

8

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

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