开发者

Equivalent to F#’s Seq.scan() method in Python?

开发者 https://www.devze.com 2022-12-29 15:53 出处:网络
Is there a function like a F#\'s Seq.scan() in P开发者_StackOverflowython? I want to do some cumsum() or cumproduct() kind of things without looping.Ignacio\'s solution is almost right I think, but r

Is there a function like a F#'s Seq.scan() in P开发者_StackOverflowython?

I want to do some cumsum() or cumproduct() kind of things without looping.


Ignacio's solution is almost right I think, but requires a operator of type ('a -> 'a -> 'a) and doesn't yield the first element.

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]

Specifically, the type of Seq.scan is

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

The default approach in Python is to write a scan with the type

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

This comes from the way that Python specifies reduce, which has the same type by default.


Nope.

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


If it's only about doing cumsum/cumprod operations, then you should look at numpy's super efficient cumsum and cumprod operations on arrays.


Aggregate functions would use reduce rather than map.

See http://docs.python.org/library/functions.html for more info


you can use accumulate function get the same functionality which is python equivalent to scan:

from itertools import accumulate
nums=[1,2,3,4,5]
nums_added=list(accumulate(nums,lambda x,y:x+y))
print(nums_added)

#prints
# [1,3,6,10,15]

You can also use rx (reactive extension) to use scan operator. It's a external library. so you need to install it before using it. with rx you can do something like this:

from rx import  from_, operators as op
nums=[1,2,3,4,5]
source=from_(nums).pipe(op.scan(lambda x,y:x+y))
source.subscribe(lambda num:print(num)

#prints
#1
#3
#6
#10
#15

rx can do much more than this it allows you to do reactive programming. To learn more visit this: http://reactivex.io


I'm not sure but give this a try

map(function, iterable, ...)¶

More on this on docs.python

0

精彩评论

暂无评论...
验证码 换一张
取 消