2011-08-17 38 views
5

Tôi đọc một số điều về slice trong python3. Sau đó, tôi đã viết một chương trình, đã cố gắng triển khai getitem (tự, slice). Mã dưới đây:[python]: cách triển khai slice trong python3?

class NewList: 
    def __init__(self, lst): 
     print('new list') 
     self._list = lst 
    def __getitem__(self, x): 
     if type(x) is slice: 
      return [ self._list[n] for n in range(x.start, x.stop, x.step) ] #error? 
     else: 
      return self._list[x] 
    ... 

nl1 = NewList([1,2,3,4,5]) 
nl1[1:3] #error occurs 

sau đó tôi phát hiện ra x.step là Không, làm cho phạm vi tăng ngoại lệ. Vì vậy, tôi nên triển khai phương thức getitem như thế nào?

+0

Ngoài ra, lớp 'NewList' của bạn nên được kế thừa từ' danh sách' ... – JBernardo

+0

@JBernardo --Bạn có nghĩa là tôi nên tránh sử dụng các đối tượng slice một cách rõ ràng không? – Alcott

Trả lời

2

Bạn cần phải sử dụng phương pháp slice.indices. Với độ dài của chuỗi của bạn, nó trả về một bộ khởi động, dừng lại, bước:

>>> s = slice(2, 5, None) 
>>> s.indices(10) 
(2, 5, 1) 

>>> [x for x in range(*s.indices(10))] 
[2, 3, 4] 

>>> s.indices(3) 
(2, 3, 1) 

>>> s.indices(0) 
(0, 0, 1) 
0

khoảng x.step or 1?

class NewList: 
    def __init__(self, lst): 
     print('new list') 
     self._list = lst 
    def __getitem__(self, x): 
     if type(x) is slice: 
      return [ self._list[n] for n in range(x.start, x.stop, x.step or 1) ] #error? 
     else: 
      return self._list[x] 

nl1 = NewList([1,2,3,4,5]) 
nl1[1:3] 
+0

ya, đó là cách phá vỡ vấn đề, nhưng theo những gì tôi đọc, không. – Alcott

2

Nếu x là một lát, bạn có thể làm tương tự như các điều kiện khác:

return self._list[x] 
+0

hoàn toàn có, nhưng tôi chỉ muốn biết làm thế nào để làm điều đó bản thân mình – Alcott

+0

@Alcott, không chắc chắn những gì bạn có nghĩa là do "làm điều đó bản thân mình". –

+1

xin lỗi, ý tôi là tôi muốn biết cách __getitem __ (self, slice) được thực hiện trong danh sách. – Alcott

4

Trong trường hợp bạn không biết chiều dài của đối tượng có một thủ thuật rõ ràng để phá vỡ tham số bắt buộc này. Ví dụ một chuỗi vô hạn của GetItem có thể trông như thế này:

def __getitem__(self, key) : 
    if isinstance(key, slice) : 
     m = max(key.start, key.stop) 
     return [self[ii] for ii in xrange(*key.indices(m+1))] 
    elif isinstance(key, int) : 
     #Handle int indices 

Nó sẽ chỉ thất bại nếu bạn không cho bắt đầu và ngừng nhưng với việc kiểm tra cho Không điều này có thể bị xử lý quá.

+0

'xrange' không tồn tại trong python3, thay vào đó chúng ta nên sử dụng' dải ô'. cũng sử dụng việc triển khai này, bạn không thể có các slice như '[: 4]' vì 'max' không thể xử lý kiểu' None'. Thay vào đó bạn nên kiểm tra xem bắt đầu và dừng không phải là 'None', và nếu chúng có, gán chúng cho 0 và len của các mục tương ứng. Ngoài ra, bạn cũng nên bao gồm 'key.step' trong' dải ô'. – sazary

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