2012-02-28 52 views
41

Tại sao không 'example'[999:9999] dẫn đến lỗi? Kể từ 'example'[9], động lực đằng sau nó là gì?Tại sao chỉ mục cắt chuỗi con ra khỏi phạm vi hoạt động trong Python?

Từ hành vi này tôi có thể giả định rằng 'example'[3], về cơ bản/nội bộ, không giống như 'example'[3:4], mặc dù cả hai kết quả trong cùng một chuỗi 'm'.

+9

'[999: 9999]' không phải là chỉ mục, đó là một lát và có ngữ nghĩa khác nhau. Từ phần giới thiệu python: "Chỉ số slice thoái hóa được xử lý một cách duyên dáng: chỉ mục quá lớn được thay thế bằng kích thước chuỗi, một giới hạn trên nhỏ hơn giới hạn dưới trả về một chuỗi rỗng". – geoffspear

+0

@Wooble đó là câu trả lời thực tế – jondavidjohn

+1

@Wooble Và bạn có biết tại sao nó theo cách này? Cảm ơn sự trình bày rõ ràng của bạn. – ijverig

Trả lời

5

Cắt lát không được kiểm tra bởi các loại được cài sẵn. Và mặc dù cả hai ví dụ của bạn dường như có cùng kết quả, chúng hoạt động khác nhau; hãy thử chúng với một danh sách để thay thế.

31

Về cơ bản, bạn đã trả lời câu hỏi của riêng mình. Cắt bên ngoài các giới hạn của một chuỗi (ít nhất là để xây dựng) không gây ra lỗi. Nó có ý nghĩa khi bạn nghĩ về nó. Việc lập chỉ mục trả về một mục duy nhất, nhưng việc cắt trả về một chuỗi các mục. Vì vậy, khi bạn cố gắng lập chỉ mục một giá trị không tồn tại, không có gì để trả lại; nhưng khi bạn cắt một chuỗi bên ngoài giới hạn, bạn vẫn có thể trả về một chuỗi rỗng.

Cũng lưu ý rằng có sự khác biệt chung giữa x[3]x[3:4]. Ví dụ:

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

Lý do chúng giống nhau trong trường hợp chuỗi không có ký tự riêng lẻ bên ngoài chuỗi; một ký tự đơn chỉ là chuỗi gồm 1 ký tự.

+1

Một chỉ mục ngoài phạm vi có thể đã trả về 'Không có' thay vì lỗi - đó là quy ước Python thông thường khi bạn không có gì để trả lại. –

+3

@MarkRansom, đó là sự thật; nhưng trả về 'None' trong trường hợp này sẽ làm cho khó có thể biết được giữa một chỉ số vượt quá giới hạn và giá trị' None' bên trong một danh sách. Nhưng ngay cả khi có một giải pháp cho điều đó, nó vẫn còn rõ ràng với tôi rằng trở về một chuỗi rỗng là điều phải làm khi đưa ra một out-of-bounds slice. Nó tương tự như thực hiện các liên minh của hai bộ rời rạc. – senderle

+0

Chỉ cần rõ ràng, tôi không nói rằng bạn đã sai. Tôi thấy quan điểm của bạn về các giá trị 'None' trong một danh sách. –

8

Vì lợi ích của việc thêm một câu trả lời rằng chỉ đến một phần mạnh mẽ trong documentation:

Cho một biểu lát như s[i:j:k],

The slice of s from i to j with step k is defined as the sequence of items with index x = i + n*k such that 0 <= n < (j-i)/k. In other words, the indices are i, i+k, i+2*k, i+3*k and so on, stopping when j is reached (but never including j). When k is positive, i and j are reduced to len(s) if they are greater

nếu bạn viết s[999:9999], trăn đang trở lại s[len(s):len(s)] từ len(s) < 999 và bước của bạn là tích cực (1 - mặc định).

+0

Có lẽ khi 'k' là dương,' i' và 'j' cũng được tăng lên' -len (s) 'khi chúng nhỏ hơn? ví dụ. 's = 'bac'; s [-100: 2] == s [-len (s): 2] ' –

+0

@Chris_Rands Khi' k' là dương, Python sẽ mở rộng 'i' và' j' sao cho chúng phù hợp với giới hạn của chuỗi. Trong ví dụ của bạn, 's [-100: 2] == s [0: 2]' ('== s [-len (s): 2]', nhân tiện). Tương tự, 's [-100: 100] == s [0: 2]'. – tylerc0816

Các vấn đề liên quan