Làm thế nào để bạn sử dụng cú pháp cắt dấu chấm lửng trong Python?


Câu trả lời:


102

Ellipsishoặc ...không phải là một tính năng ẩn, nó chỉ là một hằng số. Nó khá khác với, ví dụ, javascript ES6, đây là một phần của cú pháp ngôn ngữ. Không có lớp dựng sẵn hoặc cấu trúc ngôn ngữ Python nào sử dụng nó.

Vì vậy, cú pháp cho nó phụ thuộc hoàn toàn vào bạn, hoặc người khác, có mã viết để hiểu nó.

Numpy sử dụng nó, như đã nêu trong tài liệu . Một số ví dụ ở đây .

Trong lớp của riêng bạn, bạn sẽ sử dụng nó như thế này:

>>> class TestEllipsis(object):
...     def __getitem__(self, item):
...         if item is Ellipsis:
...             return "Returning all items"
...         else:
...             return "return %r items" % item
... 
>>> x = TestEllipsis()
>>> print x[2]
return 2 items
>>> print x[...]
Returning all items

Tất nhiên, có tài liệu python , và tài liệu tham khảo ngôn ngữ . Nhưng những điều đó không hữu ích lắm.


6
có vẻ khá hỏng vì cách "propper" để nói tất cả các mục là >>> x [:] >>> x [:, 1: 2]
Ronny

30
@Ronny: Vấn đề là thể hiện một số cách sử dụng Ellipsis tùy chỉnh.
nosklo

7
Các liên kết dường như bị phá vỡ.
SwiftsNamesake

229

Dấu chấm lửng được sử dụng trong numpy để cắt các cấu trúc dữ liệu chiều cao hơn.

Tại thời điểm này,: nó được thiết kế để chèn nhiều lát ( ) đầy đủ để mở rộng lát cắt đa chiều cho tất cả các kích thước .

Ví dụ :

>>> from numpy import arange
>>> a = arange(16).reshape(2,2,2,2)

Bây giờ, bạn có một ma trận 4 chiều có thứ tự 2x2x2x2. Để chọn tất cả các yếu tố đầu tiên trong chiều thứ 4, bạn có thể sử dụng ký hiệu dấu chấm lửng

>>> a[..., 0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

tương đương với

>>> a[:,:,:,0].flatten()
array([ 0,  2,  4,  6,  8, 10, 12, 14])

Trong các triển khai của riêng bạn, bạn có thể bỏ qua hợp đồng được đề cập ở trên và sử dụng nó cho bất cứ điều gì bạn thấy phù hợp.


Có thể tôi sai nhưng không phải nó a[:,:,:,0]sẽ trả lại một bản sao và a[...,0]sẽ trả lại "lượt xem" chứ không phải bản sao? Tôi đã thử chạy id()với cả hai phiên bản và cho mảng 3 mờ: a[:,:,:, 0], a[:,:,:, 1], a[:,:,:, 2] tất cả đều có id khác nhau trong khi: a[..., 0], a[..., 1], a[..., 2] tất cả đều có cùng id.
mohitsharma44

@ mohitsharma44 không có trên máy của tôi;) id()trả về cùng một giá trị cho cả hai. Cũng kiểm tra với __array_interface__['data']hiển thị cùng một địa chỉ bộ nhớ.
BoltzmannBrain

Tôi thấy chúng ta có thể sử dụng a[indexes, ...]trong khi a là mảng 1 chiều!
acgtyrant

1
Dấu chấm lửng cũng hữu ích cho các cấu trúc dữ liệu không thứ nguyên. Chúng là cách duy nhất tôi biết để viết vào vô hướng numpy.ndarrays, vd: my_scalar = np.asarray (3); my_scalar [...] = 5. Nếu bạn thực hiện my_scalar [:] = 5, bạn sẽ nhận được một lỗi chính xác, bởi vì không có thứ nguyên 0 nào cho: lặp đi lặp lại.
SuperElectric

1
@SuperElectric Bạn cũng có thể sử dụng my_scalar.itemset (scalarvalue). Tất nhiên, my_scalar [...] = scalar_value ngắn hơn, nhưng bạn đã nói trong nhận xét trên, đó là cách duy nhất bạn biết. Chỉ cần đưa ra một sự thay thế.
kamathln

70

Đây là một cách sử dụng khác cho Ellipsis, không liên quan gì đến các lát: Tôi thường sử dụng nó trong giao tiếp nội bộ với hàng đợi, như một dấu hiệu báo hiệu "Xong"; nó ở đó, nó là một vật thể, nó là một con đơn và tên của nó có nghĩa là "thiếu" và nó không phải là Không được sử dụng quá mức (có thể được xếp vào hàng đợi như một phần của luồng dữ liệu thông thường). YMMV.


14
Có thể không rõ ràng hơn khi chỉ nói: "Xong = object ()" ở đâu đó và chỉ sử dụng nó?
Brandon Rhodes

12
Không nhất thiết - nó yêu cầu bạn thực sự nói Done = object () ở đâu đó. Các giá trị Sentinel không nhất thiết là một điều xấu - và sử dụng các singletons Python gần như vô dụng như các Sentinel không phải là IMO khủng khiếp (Ellipsis và () là những thứ tôi đã sử dụng khi Không ai có thể nhầm lẫn).
Rick Copeland

6
Về Done = object (), tôi nghĩ rằng sử dụng Ellipsis sẽ tốt hơn, đặc biệt nếu bạn đang sử dụng nó để liên lạc với hàng đợi. Nếu bạn chuyển từ giao tiếp nội bộ sang giao tiếp nội bộ, id (Xong) sẽ không giống nhau trong quy trình khác và không có gì để phân biệt đối tượng này với đối tượng khác. Id của Ellipsis cũng sẽ không giống nhau, nhưng ít nhất loại này sẽ giống nhau - đây là điểm của một người độc thân.
Tristan Reid

Câu hỏi cho biết "Làm thế nào để bạn sử dụng dấu chấm lửng" nhưng tôi tin rằng bạn đã sử dụng sai cách này. Nó có nhiều cách hiểu. Nhưng tôi nghĩ chính xác là: "Ellipsis được sử dụng như thế nào?" tức là "Những bước tôi nên làm để sử dụng Ellipsis trong mã của riêng tôi.".
Lyndon White

6

Như đã nêu trong các câu trả lời khác, nó có thể được sử dụng để tạo các lát. Hữu ích khi bạn không muốn viết nhiều ký hiệu lát ( :) hoặc khi bạn không chắc chắn về chiều của mảng đang được thao tác.

Điều tôi nghĩ quan trọng cần làm nổi bật, và điều còn thiếu ở các câu trả lời khác, là nó có thể được sử dụng ngay cả khi không có thêm kích thước nào để điền vào.

Thí dụ:

>>> from numpy import arange
>>> a = arange(4).reshape(2,2)

Điều này sẽ dẫn đến lỗi:

>>> a[:,0,:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: too many indices for array

Điều này sẽ làm việc:

a[...,0,:]
array([0, 1])
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.