2014-04-07 15 views
11

Tôi có một tập lệnh cố đọc điểm bắt đầu và điểm kết thúc cho tập hợp con thông qua tìm kiếm nhị phân, sau đó các giá trị này được sử dụng để tạo một lát để xử lý tiếp.Tại sao `for x trong danh sách [None: None]:` làm việc?

Tôi nhận thấy rằng khi các biến này không được đặt (tìm kiếm trả về Không) mã sẽ vẫn chạy và cuối cùng tôi nhận thấy rằng một lát trải dài từ None đến None hoạt động như kiểm tra toàn bộ danh sách (xem ví dụ bên dưới)).

#! /usr/bin/env python 
list = [1,2,3,4,5,6,7,8,9,10] 
for x in list[None:None]: 
    print x 

Có ai biết lý do tại sao lựa chọn đã được thực hiện để xem list[None:None] đơn giản là list[:], ít nhất đó là những gì tôi nghĩ điều đó xảy ra (đúng cho tôi nếu tôi sai). Cá nhân tôi sẽ nghĩ rằng ném một TypeError sẽ là mong muốn trong một trường hợp như vậy.

+3

Tôi nghi ngờ lựa chọn này thực sự được thực hiện để xem 'danh sách [:] 'như' danh sách [Không: Không] '. – robert

+1

Có lẽ chính xác trường hợp sử dụng của bạn. Nếu bạn có một điểm 'start' và' end' mà bạn đang thiết lập từ một nơi khác, nếu 'list [None: None]' không hoạt động thì bạn sẽ không có cơ hội phục hồi.Bằng cách này, bạn có thể kiểm tra trước khi tay 'nếu không có bất kỳ (x là Không cho x trong [bắt đầu, kết thúc]):' –

Trả lời

16

Nonemặc định cho vị trí lát. Bạn có thể sử dụng None hoặc bỏ qua giá trị hoàn toàn, tại thời điểm đó, None được chuyển cho bạn.

None là mặc định bởi vì bạn có thể sử dụng bước đi tiêu cực, tại thời điểm nào vị trí bắt đầu và kết thúc mặc định là đã thay đổi. So sánh ví dụ list[0:len(list):-1] đến list[None:None:-1].

Sử dụng Python None cho 'giá trị không được chỉ định' trong toàn bộ thư viện chuẩn; đây không phải là ngoại lệ.

Lưu ý rằng nếu lớp học của bạn thực hiện các object.__getitem__ hook, bạn sẽ có được thông qua một đối tượng slice() với sự bắt đầu, kết thúc và sải chân các thuộc tính thiết lập để None cũng như:

>>> class Foo(object): 
...  def __getitem__(self, key): 
...   print key 
... 
>>> Foo()[:] 
slice(None, None, None) 

Kể từ Foo() thậm chí không thực hiện một __len__ có mặc định sử dụng None là hoàn toàn hợp lý ở đây.

+0

Tôi sẽ phải có chức năng tìm kiếm nhị phân của tôi trả lại một cái gì đó khác hơn là Không có sau đó. Cảm ơn bạn đã xây dựng. –

+0

@BasJansen Bạn có thể kiểm tra kết quả cho 'Không: Không có gì' hoặc ném một ngoại lệ thay thế. Cả hai đều khá Pythonic. Sử dụng các giá trị "ma thuật" đặc biệt thường không phải là một lựa chọn tốt. – Ber

+0

@BasJansen Chức năng tìm kiếm sẽ trả về các giá trị liên quan đến tìm kiếm, không dựa trên cách bạn sử dụng chúng ngoài tìm kiếm (ví dụ: không trả về '(0, 0)' để bạn có một lát trống với '[0 : 0] ', nếu zeroes không phải là kết quả tìm kiếm hợp lý). Giải pháp tốt hơn là kiểm tra 'None' trước khi bạn thử slice. – nmclean

1

None là biểu diễn thông thường cho "tham số không được đưa ra", vì vậy bạn có thể truyền đạt sự kiện cho một hàm. Bạn thường sẽ thấy chức năng hoặc các phương pháp tuyên bố như thế này

def f(p=None): 
    if f is None: 
     f = some_default_value() 

Tôi đoán này làm cho sự lựa chọn rõ ràng: Hãy sử dụng None bạn có thể nói với các slicer sử dụng giá trị mặc định của nó.

3

Tôi cũng nghĩ rằng list[None:None] được hiểu là list[:]. Đây là hành vi có ích vì bạn có thể làm điều gì đó như thế này:

return list[some_params.get('start'):some_params.get('end')] 

Nếu danh sách cắt sẽ không làm việc với None, bạn sẽ phải kiểm tra xem startendNone mình:

if some_params.get('start') and some_params.get('end'): 
    return list[some_params.get('start'):some_params.get('end')] 
elif some_params.get('start'): 
    return list[some_params.get('start'):] 
elif end: 
    return list[:some_params.get('end')] 
else: 
    return list[:] 

May mắn thay đây không phải là trường hợp trong Python :).

+0

Tôi đã mong đợi rằng một lát giữa hai biến giống hệt nhau sẽ là 0 nhưng như là rõ ràng từ câu hỏi của tôi và đó là câu trả lời tiếp theo nó được lấy là 'mặc định' hoặc 'không xác định'. –

+2

Có thể được chơi golf để 'danh sách trả lại [some_params.get ('start'): some_params.get ('end')]'. – RemcoGerlich

+0

@RemcoGerlich Đúng, đã cập nhật câu trả lời – rednaw

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