Эквивалентно методу F # Seq.scan () в Python? - PullRequest
8 голосов
/ 10 мая 2010

Есть ли такая функция, как F # Seq.scan() в Python?

Я хочу сделать некоторые вещи cumsum() или cumproduct() без зацикливания.

Ответы [ 5 ]

5 голосов
/ 10 мая 2010

Я думаю, что решение Игнасио почти правильное, но требует оператора типа ('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, который по умолчанию имеет тот же тип.

5 голосов
/ 10 мая 2010

Нет.

def scan(op, seq):
  it = iter(seq)
  result = next(it)
  for val in it:
    result = op(result, val)
    yield result
2 голосов
/ 11 мая 2010

Если речь идет только о выполнении операций cumsum / cumprod, то вам следует обратить внимание на суперэффективные cumsum и cumprod операции над массивами.

0 голосов
/ 10 мая 2010

Я не уверен, но попробуйте

map(function, iterable, ...)¶

Подробнее об этом на docs.python

0 голосов
/ 10 мая 2010

Агрегированные функции будут использовать reduce вместо map.

Подробнее см. http://docs.python.org/library/functions.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...