Câu trả lời:
nó có nghĩa là 'không có gì cho đối số thứ nhất, không có gì cho lần thứ hai và nhảy qua ba'. Nó được mọi thứ ba của chuỗi được cắt lát. Lát mở rộng là những gì bạn muốn. Mới trong Python 2.3
range(10)[::3]
đầu ra[0, 3, 6, 9]
::
như [n ::]. Vậy nó có nghĩa là n
gì?
seq[::n]
là một chuỗi của mỗi n
mục thứ trong toàn bộ chuỗi.
Thí dụ:
>>> range(10)[::2]
[0, 2, 4, 6, 8]
Cú pháp là:
seq[start:end:step]
Vì vậy, bạn có thể làm:
>>> range(100)[5:18:2]
[5, 7, 9, 11, 13, 15, 17]
s[i:j:k]
là, theo tài liệu , "lát s từ i đến j với bước k". Khi i
và j
vắng mặt, toàn bộ chuỗi được giả định và do đó s[::k]
có nghĩa là "mọi mục thứ k".
Đầu tiên, hãy khởi tạo một danh sách:
>>> s = range(20)
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Hãy lấy mọi thứ thứ 3 từ s
:
>>> s[::3]
[0, 3, 6, 9, 12, 15, 18]
Hãy lấy mọi thứ thứ 3 từ s[2:]
:
>>> s[2:]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> s[2::3]
[2, 5, 8, 11, 14, 17]
Hãy lấy mọi thứ thứ 3 từ s[5:12]
:
>>> s[5:12]
[5, 6, 7, 8, 9, 10, 11]
>>> s[5:12:3]
[5, 8, 11]
Hãy lấy mọi thứ thứ 3 từ s[:10]
:
>>> s[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> s[:10:3]
[0, 3, 6, 9]
Ví dụ trực quan này sẽ chỉ cho bạn cách chọn các phần tử gọn gàng trong Ma trận NumPy (mảng 2 chiều) theo cách khá thú vị (tôi hứa). Bước 2 dưới đây minh họa việc sử dụng "dấu hai chấm" đó ::
trong câu hỏi.
(Chú ý: đây là ví dụ cụ thể về mảng NumPy với mục đích minh họa trường hợp sử dụng "dấu hai chấm" ::
để nhảy các phần tử trong nhiều trục. Ví dụ này không bao gồm các cấu trúc dữ liệu Python nguyên gốc như List
).
Giả sử chúng ta có một ma trận NumPy trông như thế này:
In [1]: import numpy as np
In [2]: X = np.arange(100).reshape(10,10)
In [3]: X
Out[3]:
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
[20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
[40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74, 75, 76, 77, 78, 79],
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89],
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
Nói vì một số lý do, sếp của bạn muốn bạn chọn các yếu tố sau:
"Nhưng làm thế nào ???" ... Đọc tiếp! (Chúng ta có thể làm điều này theo cách tiếp cận 2 bước)
Chỉ định "chỉ mục bắt đầu" và "chỉ mục kết thúc" theo cả hai hướng theo hàng và theo cột.
Trong mã:
In [5]: X2 = X[2:9,3:8]
In [6]: X2
Out[6]:
array([[23, 24, 25, 26, 27],
[33, 34, 35, 36, 37],
[43, 44, 45, 46, 47],
[53, 54, 55, 56, 57],
[63, 64, 65, 66, 67],
[73, 74, 75, 76, 77],
[83, 84, 85, 86, 87]])
Bây giờ hãy lưu ý rằng chúng ta vừa thu được tập hợp con của mình, với việc sử dụng kỹ thuật lập chỉ mục bắt đầu và kết thúc đơn giản. Tiếp theo, làm thế nào để thực hiện "nhảy" đó ... (đọc tiếp!)
Bây giờ chúng ta có thể chỉ định "các bước nhảy" theo cả hai hướng theo hàng và theo cột (để chọn các phần tử theo cách "nhảy") như sau:
Trong mã (lưu ý dấu hai chấm):
In [7]: X3 = X2[::3, ::2]
In [8]: X3
Out[8]:
array([[23, 25, 27],
[53, 55, 57],
[83, 85, 87]])
Chúng tôi vừa chọn tất cả các yếu tố theo yêu cầu! :)
Bây giờ chúng ta đã biết khái niệm này, chúng ta có thể dễ dàng kết hợp bước 1 và bước 2 thành một bước hợp nhất - cho sự gọn nhẹ:
In [9]: X4 = X[2:9,3:8][::3,::2]
In [10]: X4
Out[10]:
array([[23, 25, 27],
[53, 55, 57],
[83, 85, 87]])
Làm xong!
X[2:9,3:8][::3,::2] = 0
(để thay thế các mục được đánh dấu thành 0). Nếu bạn nhập X
lại, bạn sẽ thấy tất cả các mục được đánh dấu hiện được đặt thành 0
.
Khi cắt trong Python tham số thứ ba là bước. Như những người khác đã đề cập, hãy xem Extended Slices để có cái nhìn tổng quan đẹp.
Với kiến thức này, [::3]
chỉ có nghĩa là bạn chưa chỉ định bất kỳ chỉ số bắt đầu hoặc kết thúc nào cho lát cắt của mình. Vì bạn đã chỉ định một bước, 3
nên điều này sẽ mất mỗi lần nhập thứ ba something
bắt đầu ở chỉ mục đầu tiên. Ví dụ:
>>> '123123123'[::3]
'111'
Bạn cũng có thể sử dụng ký hiệu này trong các lớp tùy chỉnh của riêng bạn để làm cho nó làm bất cứ điều gì bạn muốn
class C(object):
def __getitem__(self, k):
return k
# Single argument is passed directly.
assert C()[0] == 0
# Multiple indices generate a tuple.
assert C()[0, 1] == (0, 1)
# Slice notation generates a slice object.
assert C()[1:2:3] == slice(1, 2, 3)
# If you omit any part of the slice notation, it becomes None.
assert C()[:] == slice(None, None, None)
assert C()[::] == slice(None, None, None)
assert C()[1::] == slice(1, None, None)
assert C()[:2:] == slice(None, 2, None)
assert C()[::3] == slice(None, None, 3)
# Tuple with a slice object:
assert C()[:, 1] == (slice(None, None, None), 1)
# Ellipsis class object.
assert C()[...] == Ellipsis
Sau đó chúng ta có thể mở các đối tượng lát như:
s = slice(1, 2, 3)
assert s.start == 1
assert s.stop == 2
assert s.step == 3
Điều này đáng chú ý được sử dụng trong Numpy để cắt các mảng đa chiều theo bất kỳ hướng nào.
Tất nhiên, bất kỳ API lành mạnh nào cũng nên sử dụng ::3
với ngữ nghĩa "cứ 3" thông thường.
Các liên quan Ellipsis
được đề cập sâu hơn tại: Đối tượng Ellipsis làm gì?
Python sử dụng :: để phân tách giá trị Kết thúc, Bắt đầu và Bước.
[5::]
. Vậy 5 nghĩa là gì?