2010-08-25 25 views

Trả lời

21

Nó không. Lựa chọn thay thế của bạn trong trường hợp này là anyall.

result = reduce(operator.and_, [False] * 1000) 
result = reduce(operator.or_, [True] * 1000) 

có thể được thay thế bằng

result = all([False] * 1000) 
result = any([True] * 1000) 

mà làm ngắn mạch.

Kết quả thời gian hiển thị sự khác biệt:

In [1]: import operator 

In [2]: timeit result = reduce(operator.and_, [False] * 1000) 
10000 loops, best of 3: 113 us per loop 

In [3]: timeit result = all([False] * 1000) 
100000 loops, best of 3: 5.59 us per loop 

In [4]: timeit result = reduce(operator.or_, [True] * 1000) 
10000 loops, best of 3: 113 us per loop 

In [5]: timeit result = any([True] * 1000) 
100000 loops, best of 3: 5.49 us per loop 
+0

Bạn nói đúng. 'any()' và 'all()' dường như chính xác những gì tôi cần (và có thể rõ ràng hơn). Làm thế nào bạn làm điều đó thời gian? –

+1

Tôi đang sử dụng lệnh 'ipython' và lệnh' timeit' của nó. Nhưng Python có một mô-đun timeit. Vì vậy, bạn có thể làm 'python -mtimeit" result = any ([True] * 10) "' từ dòng lệnh cho thời gian. –

5

Không chỉ giảm() không ngắn mạch, nó có thể không thể ngắn mạch trên tất cả các mặt hàng được giảm, bởi vì nó chỉ xem xét các mục hai tại một thời gian. Ngoài ra, nó không có ý tưởng về các điều kiện theo đó chức năng được sử dụng ngắn mạch. (Sẽ rất tiện lợi nếu các hàm có thể có một thuộc tính cho biết giá trị mà tại đó chúng bắt đầu đoản mạch, mà giảm() sau đó có thể nhận ra và sử dụng, nhưng không.)

+0

Đây là lý do tại sao người dùng Lisp yêu Lisp rất nhiều - bởi vì tất cả các chức năng đều là dữ liệu, đó là (chính) có thể thực hiện loại phát hiện này. – Lucretiel

3

Nó cũng có thể là có thể (xem fate of reduce) rằng việc thay thế sẽ giảm bớt việc thực hiện sẽ hoạt động tốt.

Ý tưởng này đã làm việc hoàn hảo để tôi làm cho mọi thứ minh bạch hơn trong thiết kế.

def ipairs(seq): 
    prev = None 
    for item in seq: 
     if prev is not None: 
      yield (prev, item) 
     prev = item 

def iapply(seq, func): 
    for a, b in ipairs(seq): 
     yield func(a, b) 

def satisfy(seq, cond): 
    return all(iapply(seq, cond)) 

def is_uniform(seq): 
    return satisfy(seq, lambda a, b: a == b) 

Như bạn thấy giảm được chia thành iapply <-ipairs.

Xin lưu ý nó không phải là tương đương với

def ireduce(seq, func): 
    prev = None 
    for item in seq: 
     if prev is None: 
      prev = item 
     else: 
      prev = func(prev, item) 
    return prev 
2

Gấu nhớ rằng đánh giá ngắn mạch không phải lúc nào những gì bạn muốn. "Sửa chữa" giảm ngắn mạch sẽ là một sai lầm vì lý do đó. Ví dụ, gần đây tôi đã phải thay đổi việc sử dụng all() để giảm() trong khi xử lý danh sách biểu mẫu trong django: Tôi muốn báo cáo bất kỳ vấn đề nào is_valid(), không chỉ là vấn đề đầu tiên.

+0

nó có thể sử dụng một đối số từ khóa cho các tiêu chí ngắn mạch, các nội trang khác làm: giảm (operator.or, mylist, key = lambda x:: x <0) – LBarret

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