2010-03-03 41 views
6

Tôi cần một hàm, có khả năng lặp qua bộ sưu tập, gọi hàm được cung cấp cùng với phần tử của tập hợp dưới dạng tham số và trả về tham số hoặc chỉ số khi nhận được "True" từ hàm được cung cấp.Python - chức năng "tìm"?

Nó được somethong như thế này:

def find(f, seq, index_only=True, item_only=False): 
    """Return first item in sequence where f(item) == True.""" 
    index = 0 
    for item in seq: 
     if f(item): 
      if index_only: 
       return index 
      if item_only: 
       return item 
      return index, item 
     index+= 1 
    raise KeyError 

Vì vậy, tôi tự hỏi liệu có bất cứ điều gì như thế trong standart python công cụ?

+2

Đoạn mã của OP là cách trực tiếp hơn (nếu chỉ dài hơn một chút) để thể hiện yêu cầu; nó cũng có thể được quy định theo cách, tùy thuộc vào tình hình. Tuy nhiên, từ các câu trả lời, có một cái nhìn rất hữu ích: 'liên quan đến vòng lặp, khi nghi ngờ, hãy tham khảo/xem xét itertools'. – mjv

Trả lời

2

Bạn có thể sử dụng itertools.dropwhile để bỏ qua các mục mà hàm được cung cấp trả về False, sau đó lấy mục đầu tiên của phần còn lại (nếu có). Nếu bạn cần chỉ mục thay vì mục, hãy kết hợp enumerate từ phần Công thức của itertools docs.

Để đảo ngược các giá trị chân lý được trả về bởi các chức năng cung cấp, sử dụng một lambda (lambda x: not pred (x), nơi pred là chức năng được cung cấp) hoặc một wrapper tên:

def negate(f): 
    def wrapped(x): 
     return not f(x) 
    return wrapped 

Ví dụ:

def odd(x): return x % 2 == 1 
itertools.dropwhile(negate(odd), [2,4,1]).next() 
# => 1 

chí này ném StopIteration nếu không tìm thấy mục phù hợp; quấn nó trong một chức năng của riêng bạn để ném một ngoại lệ của sự lựa chọn của bạn để thay thế.

+0

:(Tôi nghĩ câu hỏi của OP chính là câu trả lời, điều này có thể nhiều hơn một chút cho việc lặp lại đơn giản –

+0

Tôi đồng ý với Anurag, nhưng nếu 'itertools' được sử dụng, tôi nghĩ' ifilter' sẽ đơn giản hơn. (lẻ, [2,4,1]). next() ' – tgray

+0

Tôi có khuynh hướng đồng ý về' ifilter'. Ngoài ra, đoạn mã của OP thực sự giải quyết được vấn đề cơ bản tốt, vẫn còn, tự hỏi có gì trong đó lib tiêu chuẩn để giúp tránh viết mã cho các công cụ như thế này có vẻ khá hợp lý.Tôi muốn nói bình luận của mjv về câu hỏi tổng kết bài học quan trọng ở đây một cách hoàn hảo. –

3

Tôi không nghĩ rằng có bất kỳ chức năng như vậy với ngữ nghĩa chính xác như vậy, và anyway chức năng của bạn là ngắn, đủ tốt và bạn có thể dễ dàng cải thiện nó để sử dụng sau này, vì vậy sử dụng nó.

vì đơn giản hơn là phức tạp.