Intente hacer un bucle en la función principal, llame a otra función, al final del bucle obtenga una lista de valores acumulativos:

Código como este:

    def stock_stats(i):
      tmp=[]
      tmp.append(i+10)
      yield tmp

    def main():
       for stockid in total_nos_of_stock:
       stockinfo=readstock(stockid)     
       result=stock_stats(stockinfo)
       print(list(result))

El resultado esperado debe ser [estadísticas del stock 1, estadísticas del stock 2, ..., estadísticas del stock]

Intente generador y cierre, pero no funcionó.

Sé que podría agregar los valores en el bucle principal o pasar una lista vacía a la función llamada, pero prefiero la mayor parte del cálculo en la función llamada y mantener una asignación simple en el bucle principal.

Tkyou!

-1
timeislove 28 ago. 2014 a las 13:12

3 respuestas

La mejor respuesta
class Statistician(list):

    KEYS = {'RSI':0, 'MACD':1, 'CAPRATIO':2, 'OTHER':3}

    def __init__(self):
        list.__init__(self)

    def read_stocks(self, stocks):
        for stock in stocks:
            self.read_stock(stock)

    def read_stock(self, stock):
        self.append(stock)

    def stock_stats(self, stock_info):
        if stock_info not in Statistician.KEYS.keys() :
            raise Exception('Unknow stock_info category. Please use one of the following value : {0}'.format(str(list(Statistician.KEYS.keys()))))
        return list(map(lambda x: x[Statistician.KEYS[stock_info]],self))

if __name__ == "__main__":
    stocks = [('rsi1', 'macd1','capratio1','other1'),
              ('rsi2','macd2','capratio2','other2'),
              ('rsi3', 'macd3','capratio3','other3')]
    statistician = Statistician()
    for stock in stocks :
        statistician.read_stock(stock)

    print(statistician.stock_stats('RSI'))
    print(statistician.stock_stats('MACD'))

Ejecución:

python3 sof-script.py 
['rsi1', 'rsi2', 'rsi3']
['macd1', 'macd2', 'macd3']

¿Esto coincide con tu necesidad?

================================================== ================================ EDITAR: El mismo código usando un formulario de cierre, como se solicita en los comentarios.

Suponiendo que las existencias sean constantes, podría hacerlo. Esta es la única forma de usar el cierre que tiene sentido usando esta implementación. Otros que usan un Estadístico dado y leen los datos de los bloques dentro de la función collect requieren usar un set en lugar de un list para evitar efectos secundarios y duplicación de datos.

stocks = [('rsi1', 'macd1','capratio1','other1'),
         ('rsi2','macd2','capratio2','other2'),
         ('rsi3', 'macd3','capratio3','other3')]

S = Statistician()
S.read_stocks(stocks)

#define a closure function        
def statisticCollector(statistician, key):
    def collect():
        return statistician.stock_stats(key)
    return collect

#instanciate the closed function
collectRSI = statisticCollector(S, 'RSI')
collectMACD= statisticCollector(S, 'MACD')

if __name__ == "__main__":
    print(collectRSI())
    print(collectMACD())
1
Arthur Vaïsse 4 sep. 2014 a las 09:09

Mezcló un par de conceptos hasta el punto de que es difícil decir qué está mal. La idea detrás de los generadores es que producen series de valores. No tiene sentido tener una lista al intentar yield. Así es como realmente deberías hacerlo:

def called_function(source):
    for i in source:
        yield i + 10

def main():
    print(list(called_function(range(5))))

Después de leer tu comentario, supongo que eso es lo que realmente querías:

def stock_stats(i):
  return i + 10

def main():
   result = []
   for stockid in total_nos_of_stock:
      stockinfo=readstock(stockid)     
      result.append(stock_stats(stockinfo))
   print(result)
2
Andrey 29 ago. 2014 a las 08:26

En lugar de enviar cada i rango total de envío al called_function. para que pueda yield lista total a la vez

def called_function(n):
  yield list(range(10, 10+n))

def main():
      result=called_function(5)
      print(list(result))
main()
-2
Arthur Vaïsse 28 ago. 2014 a las 09:39