2010-05-10 15 views

Respuesta

5

solución de Ignacio es casi correcta, creo, pero requiere un operador de tipo ('a ->' a -> 'a) y no produce el primer elemento.

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] 

En concreto, el tipo de Seq.scan es

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

El método por defecto en Python es escribir un scan con el tipo

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

Esto viene de la forma en que Python especifica reduce , que tiene el mismo tipo por defecto.

+1

+1, pero cedería antes de aplicar la primera reducción. No sé sobre el escaneo F # ', pero Haskell devuelve el estado inicial como primer elemento (lo cual tiene mucho sentido): scanl (+) 0 [1,2,3] # [0,1,3, 6]. – tokland

0

Agregar funciones usaría reduce en lugar de map.

Ver http://docs.python.org/library/functions.html para obtener más información

+6

reduce() devuelve el valor final solamente ... no la lista de los valores intermedios. Entonces puedo obtener sum(), pero no cumsum() –

-3

No estoy seguro, pero le daría prueba

map(function, iterable, ...)¶ 

Más sobre esto en docs.python

5

Nop.

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

Debe hacer un 'resultado de rendimiento 'antes del ciclo, de lo contrario, al resultado le faltará el primer elemento. – sepp2k

+0

Sí, los documentos de MS eran un poco vagos en cuanto a lo que 'Seq.scan <>() hizo'. –

+0

Thnx. En realidad, el Seq.scan() de F # requiere otro parámetro como un estado inicial (resultado). Thnx. –

2

Si solo se trata de realizar operaciones de cumsum/cumprod, entonces debe observar las operaciones súper eficientes de numpy cumsum y cumprod en las matrices.

Cuestiones relacionadas