2010-05-10 49 views

Trả lời

5

Giải pháp của Ignacio gần như đúng, tôi nghĩ, nhưng yêu cầu toán tử loại ('a ->' a -> 'a) và không mang yếu tố đầu tiên.

def scan(f, state, it): 
    for x in it: 
    state = f(state, x) 
    yield state 
# test 
>>> snoc = lambda xs,x: xs+[x] 
>>> list(scan(snoc, [], 'abcd')) 
[['a'], ['a', 'b'], ['a', 'b', 'c'], ['a', 'b', 'c', 'd']] 
>>> list(scan(operator.add, 0, [1,2,3])) 
[1,3,6] 

Cụ thể, các loại Seq.scan

('State -> 'T -> 'State) -> 'State -> seq<'T> -> seq<'State> 

Phương pháp mặc định trong Python là viết một scan với kiểu

('State -> 'State -> 'State) -> seq<'State> -> seq<'State> 

này xuất phát từ cách mà Python định reduce có cùng loại theo mặc định.

+1

+1, nhưng tôi muốn đạt được trước khi áp dụng mức giảm đầu tiên. Tôi không biết về quét F # ', nhưng Haskell không trả lại trạng thái ban đầu làm yếu tố đầu tiên (mà làm cho rất nhiều ý nghĩa): scanl (+) 0 [1,2,3] # [0,1,3, 6]. – tokland

0

Chức năng tổng hợp sẽ sử dụng reduce thay vì map.

Xem http://docs.python.org/library/functions.html để biết thêm

+6

reduce() trả về giá trị cuối cùng chỉ .. không phải danh sách các giá trị trung gian. Vì vậy, tôi có thể nhận được tổng(), nhưng không cumsum() –

-3

Tôi không chắc chắn nhưng cung cấp cho này một thử

map(function, iterable, ...)¶ 

Thông tin thêm về này trên docs.python

5

Nope.

def scan(op, seq): 
    it = iter(seq) 
    result = next(it) 
    for val in it: 
    result = op(result, val) 
    yield result 
+0

Bạn nên làm một 'kết quả năng suất' trước khi vòng lặp, nếu không kết quả sẽ bị thiếu yếu tố đầu tiên. – sepp2k

+0

Vâng, các tài liệu MS hơi mơ hồ về những gì 'Seq.scan <>() đã làm. –

+0

Thnx. Trên thực tế, F # 's Seq.scan() đòi hỏi một tham số như là một trạng thái ban đầu (kết quả) .. Thnx. –

2

Nếu nó chỉ là về thực hiện các hoạt động cumsum/cumprod, thì bạn nên xem các hoạt động cumsumcumprod của numpy hiệu quả trên các mảng.

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