Hướng dẫn is python slicing inclusive? - bao gồm cắt trăn?

Các câu trả lời ở trên không thảo luận về việc gán lát cắt. Để hiểu được sự phân công lát cắt, thật hữu ích khi thêm một khái niệm khác vào nghệ thuật ASCII:

                +---+---+---+---+---+---+
                | P | y | t | h | o | n |
                +---+---+---+---+---+---+
Slice position: 0   1   2   3   4   5   6
Index position:   0   1   2   3   4   5

>>> p = ['P','y','t','h','o','n']
# Why the two sets of numbers:
# indexing gives items, not lists
>>> p[0]
 'P'
>>> p[5]
 'n'

# Slicing gives lists
>>> p[0:1]
 ['P']
>>> p[0:2]
 ['P','y']

Một heuristic là, đối với một lát từ 0 đến n, nghĩ: "Zero là sự khởi đầu, bắt đầu từ đầu và lấy n vật phẩm trong một danh sách".

>>> p[5] # the last of six items, indexed from zero
 'n'
>>> p[0:5] # does NOT include the last item!
 ['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
 ['P','y','t','h','o','n']

Một heuristic khác là, "Đối với bất kỳ lát cắt nào, hãy thay thế bắt đầu bằng 0, áp dụng heuristic trước đó để kết thúc danh sách, sau đó đếm số đầu tiên trở lại để cắt các vật phẩm từ đầu"

>>> p[0:4] # Start at the beginning and count out 4 items
 ['P','y','t','h']
>>> p[1:4] # Take one item off the front
 ['y','t','h']
>>> p[2:4] # Take two items off the front
 ['t','h']
# etc.

Quy tắc đầu tiên của gán lát cắt là vì việc cắt sẽ trả về danh sách, việc gán lát cắt yêu cầu một danh sách (hoặc khác có thể điều chỉnh được):

>>> p[2:3]
 ['t']
>>> p[2:3] = ['T']
>>> p
 ['P','y','T','h','o','n']
>>> p[2:3] = 't'
Traceback (most recent call last):
  File "", line 1, in 
TypeError: can only assign an iterable

Quy tắc thứ hai của gán lát cắt, mà bạn cũng có thể thấy ở trên, là bất kỳ phần nào của danh sách được trả lại bằng cách lập chỉ mục lát cắt, đó là cùng một phần được thay đổi bằng cách gán lát cắt:

>>> p[2:4]
 ['T','h']
>>> p[2:4] = ['t','r']
>>> p
 ['P','y','t','r','o','n']

Quy tắc thứ ba của gán lát cắt là, danh sách được gán (có thể điều chỉnh được) không phải có cùng độ dài; Đụ được lập chỉ mục chỉ đơn giản là cắt ra và thay thế en masse bằng bất cứ điều gì đang được chỉ định:

>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
 ['P','y','s','p','a','m','o','n']

Phần khó nhất để làm quen là gán cho các lát trống. Sử dụng heuristic 1 và 2, thật dễ dàng để có được đầu của bạn khi lập chỉ mục một lát trống:

>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
 ['P','y','t','h']
>>> p[1:4]
 ['y','t','h']
>>> p[2:4]
 ['t','h']
>>> p[3:4]
 ['h']
>>> p[4:4]
 []

Và sau đó một khi bạn đã thấy điều đó, việc gán lát cho lát trống cũng có ý nghĩa:

>>> p = ['P','y','t','h','o','n']
>>> p[2:4] = ['x','y'] # Assigned list is same length as slice
>>> p
 ['P','y','x','y','o','n'] # Result is same length
>>> p = ['P','y','t','h','o','n']
>>> p[3:4] = ['x','y'] # Assigned list is longer than slice
>>> p
 ['P','y','t','x','y','o','n'] # The result is longer
>>> p = ['P','y','t','h','o','n']
>>> p[4:4] = ['x','y']
>>> p
 ['P','y','t','h','x','y','o','n'] # The result is longer still

Lưu ý rằng, vì chúng tôi không thay đổi số thứ hai của lát cắt (4), các mục được chèn luôn xếp ngay với 'O', ngay cả khi chúng tôi gán cho lát trống. Vì vậy, vị trí cho gán lát trống là phần mở rộng logic của các vị trí cho các bài tập lát không trống.

Sao lưu một chút, điều gì xảy ra khi bạn tiếp tục với đám rước của chúng tôi về việc đếm phần lát cắt bắt đầu?

>>> p = ['P','y','t','h','o','n']
>>> p[0:4]
 ['P','y','t','h']
>>> p[1:4]
 ['y','t','h']
>>> p[2:4]
 ['t','h']
>>> p[3:4]
 ['h']
>>> p[4:4]
 []
>>> p[5:4]
 []
>>> p[6:4]
 []

Với việc cắt lát, một khi bạn đã hoàn thành, bạn đã hoàn thành; Nó không bắt đầu cắt ngược. Trong Python, bạn không nhận được những bước tiến tiêu cực trừ khi bạn yêu cầu rõ ràng bằng cách sử dụng một số âm.

>>> p[5:3:-1]
 ['n','o']

Có một số hậu quả kỳ lạ đối với quy tắc "một khi bạn đã hoàn thành, bạn đã hoàn thành":

>>> p[5] # the last of six items, indexed from zero
 'n'
>>> p[0:5] # does NOT include the last item!
 ['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
 ['P','y','t','h','o','n']
0

Trên thực tế, so với lập chỉ mục, việc cắt Python là không có lỗi một cách kỳ lạ:

>>> p[5] # the last of six items, indexed from zero
 'n'
>>> p[0:5] # does NOT include the last item!
 ['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
 ['P','y','t','h','o','n']
1

Điều này đôi khi có thể có ích, nhưng nó cũng có thể dẫn đến hành vi hơi kỳ lạ:

>>> p[5] # the last of six items, indexed from zero
 'n'
>>> p[0:5] # does NOT include the last item!
 ['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
 ['P','y','t','h','o','n']
2

Tùy thuộc vào ứng dụng của bạn, điều đó có thể ... hoặc có thể không ... là những gì bạn đã hy vọng ở đó!


Dưới đây là văn bản của câu trả lời ban đầu của tôi. Nó rất hữu ích cho nhiều người, vì vậy tôi không muốn xóa nó.

>>> p[5] # the last of six items, indexed from zero
 'n'
>>> p[0:5] # does NOT include the last item!
 ['P','y','t','h','o']
>>> p[0:6] # not p[0:5]!!!
 ['P','y','t','h','o','n']
3

Điều này cũng có thể làm rõ sự khác biệt giữa cắt và lập chỉ mục.