2016-11-01 13 views
0

私のアプリケーションでは、基本的に "リスト内のすべての前の用語の和"を使用する必要がありますが、リストはリストではなくタプルのジェネレータです。インデックスは例としてジェネレータ式で "状態変数"を使用

「問題」1である(明らかに非動作するコードが、それはアイデアが表示されるはずです):

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) 

または最小限の作業例(これはから別の機能として愚かであることに注意してくださいitertoolsは私のためにこれを解決することができた)

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) 

今明白な「溶液」は、forループを使用することです:

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 

しかし、このような単純な「もの」のためにあまりにも冗長その方法ではないでしょうか?ああ完全酒のために、ここに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

Pythonのタプルは '(値、値、値)'のように見えます –

+2

ジェネレータの式はそれだけで、式でなければなりません。あなたはその中で代入をすることができません –

+4

ここに蓄積の実装を見てください:https://docs.python.org/3/library/itertools.html#itertools.accumulate –

答えて

2

あなたはジェネレータ式で状態を蓄積しようとしているので、あなたはあなたのためにそれを維持するために別のオブジェクトが必要になります。あなたの現在のforループソリューションは、メンテナンスと可読性に関してこれを行う最も簡単な方法でしょう。別のオプションは、必要な状態を維持してmaxに渡す独自のジェネレータを作成することです。このソリューションを提案して@パトリック・ハウのおかげで:

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()) 

うまくいけば、このコードを見ると、それを使用する正当な理由がないことを納得させるでしょう。唯一の利点は、ロジックmaxを自分で実装するのではなく、基本的にはforループのほとんどをmaxに渡していることです。あなたのケースは、このようなことを難読化することで余分なマイルを獲得しないほど十分に専門的です。

UPDATE

私はそれを使用する関数にそれを移動することにより、発電機に引数を渡す必要がなくなりました。これは、新しいコードを導入することはないので、forループと同等の実装を間違いなく実装しますが、ロジックは削除します(max)。

関連する問題