Python中等同于F#的Seq.scan()方法的是什么?

9 投票
6 回答
4153 浏览
提问于 2025-04-15 22:33

在Python里有没有类似于F#的Seq.scan()这样的函数呢?

我想做一些像cumsum()(累加和)或者cumproduct()(累积乘积)这样的操作,但不想用循环。

6 个回答

2

如果你只是想做累加和累乘的操作,那你可以看看numpy这个库里非常高效的 cumsumcumprod 函数,它们专门用来处理数组。

5

不行。

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

我觉得Ignacio的解决方案差不多是对的,但它需要一个类型为('a -> 'a -> 'a)的操作符,并且不会返回第一个元素。

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]

具体来说,Seq.scan的类型是

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

在Python中,默认的做法是写一个类型为scan的函数

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

这源于Python对reduce的定义,默认情况下它的类型是一样的。

撰写回答