2016-11-01 2 views
0

Nun in meiner Anwendung muss ich grundsätzlich die "Summe aller vorherigen Begriffe in Liste" verwenden, aber die Liste ist nicht nur eine Liste, sondern ein Generator von Tupel (wo die dritte Index ist der „anstößige“ einVerwenden Sie "state variable" in Generator Ausdruck

als Beispiel (nicht funktionierenden Code offensichtlich, aber es sollte die Idee zeigen.):

def calculate_minimal_charge_rate(self) -> float: 
    o = self.orbit 
    shadow_time = o.generate_shadow_light_time_list() 
    P = self.getIdlePowerConsumption() 
    a = 0 
    return max(a += ind[1]; P * ind[2].period/\ 
      (ind[2].period - a) for ind in shadow_time) 

Oder ein minimales Arbeitsbeispiel (beachten sie, dass dies dumm, wie ein andere Funktion aus itertools könnte das nur für mich lösen)

def calculate_minimal_charge_rate(self) -> float: 
    o = self.orbit 
    shadow_time = o.generate_shadow_light_time_list() 
    P = self.getIdlePowerConsumption() 
    a = 0 
    return max(a += ind[1]; a for ind in shadow_time) 

Nun ist die offensichtliche „Lösung“ ist die Verwendung einer for-Schleife:

def calculate_minimal_charge_rate(self) -> float: 
    o = self.orbit 
    shadow_time = o.generate_shadow_light_time_list() 
    P = self.getIdlePowerConsumption() 
    a = 0 
    max_power = 0 
    for ind in shadow_time: 
     a += ind[1] 
     preq = P * ind[2].period/\ 
       (ind[2].period - a) 
     if preq > max_power: 
      max_power = preq 
    return max_power 

ist aber nicht auf diese Weise zu ausführlich für eine solche einfache „Ding“? Oh Vollständigkeit halber hier ist orbit.generate_shadow_light_time_list():

def generate_shadow_light_time_list(self): 
    """ 
    Returns total max time in shadow 
    Iterativelly calls max_time_in_shadow for each orbit until star is found 
    """ 
    o = self 
    try: 
     while o.parent.brightness <= 0: 
      t = o.max_time_in_shadow() 
      yield (o.period - t, t, o) 
      o = o.parent.orbit 
    except AttributeError: 
     return 
    return 
+0

Tupel in Python sehen aus wie '(Wert, Wert, Wert)' –

+2

Ein Generatorausdruck muss genau das sein, ein Ausdruck. Du darfst keine Aufgaben darin machen. –

+4

Sieh dir die Implementierung von accumute hier an: https://docs.python.org/3/library/itertools.html#itertools.accumulate –

Antwort

2

Da Sie versuchen Zustand in Ihrem Generator Ausdruck zu akkumulieren, werden Sie ein eigenes Objekt benötigen es für Sie zu halten. Ihre aktuelle for Loop-Lösung ist wahrscheinlich der einfachste Weg, dies in Bezug auf Wartung und Lesbarkeit zu tun. Eine andere Möglichkeit wäre, einen eigenen Generator zu schreiben, der den benötigten Zustand erhalten und an max übergeben würde. Dank @ patrick-Haugh für die Annahme dieser Lösung:

def calculate_minimal_charge_rate(self) -> float: 
    def get_that_quantity(): 
     a = 0 
     for item in shadow_time: 
      a += item[1] 
      p = item[2].period 
      yield power * p/(p - a) 

    power = self.getIdlePowerConsumption() 
    shadow_time = self.orbit.generate_shadow_light_time_list() 
    return max(get_that_quantity()) 

Hoffentlich in diesem Code suchen, werden Sie davon überzeugen, dass es keinen guten Grund, es zu benutzen. Der einzige Vorteil ist, dass Sie die meisten Ihrer for Schleife über den Generator an max übergeben, anstatt die Logik von max selbst zu implementieren. Ihr Fall ist so spezialisiert, dass Sie wahrscheinlich keine zusätzlichen Kilometer durch die Verschleierung solcher Dinge erhalten.

UPDATE

eliminiert die Notwendigkeit I Argumente an den Generator passieren, indem sie in der Funktion zu bewegen, die es verwendet. Dies bringt die Implementierung wohl auf Augenhöhe mit der Schleife for, da sie keinen neuen Code einführt, aber die Logik max entfernt.

Verwandte Themen