2011-01-25 8 views
0

この質問をCode Review -areaに移動してください。私は以下のコードが迷惑であることを知っており、私は書き直しを完了するために重要なフィードバックを求めていたので、そこにはより適しています。範囲といくつかの定数との間の対称関係は?

Pythonでset-to-constantリレーションを書くにはどうしたらいいですか?したがって、範囲内のAの場合は、対応する定数を返します。

[0,10] <-> a 
]10,77] <-> b 
]77,\inf[ <-> c 

臭いコード、悪いです。

# Bad style 

    provSum=0 


    # TRIAL 1: messy if-clauses 
    for sold in getSelling(): 
      if (sold >=0 & sold <7700): 
        rate =0.1 
      else if (sold>=7700 & sold <7700): 
      #won't even correct mistakes here because it shows how not to do things 
        rate =0.15 
      else if (sold>=7700): 
        rate =0.20 


    # TRIAL 2: messy, broke it because it is getting too hard to read 
    provisions= {"0|2000":0.1, "2000|7700":0.15, "7700|99999999999999":0.20} 


    if int(sold) >= int(border.split("|")[0]) & int(sold) < int(border.split("|")[1]): 
      print sold, rate 
      provSum = provSum + sold*rate 
+1

'&' – rubik

+0

'&'の代わりにキーワード 'and'を使用しますが、意味的に間違っています。それは偶然でも動作するかもしれませんが、まったく間違った演算子です。 –

+0

S.Lott:通知をいただきありがとうございます。私があなたが目指しているのは、 '&'はビット単位であり、 'と'は論理的であるということです。間違って申し訳ありません。 – hhh

答えて

3

をリストが長く単なる3つのエントリよりだった場合、私はbisect.bisect()を使用します。

limits = [0, 2000, 7700] 
rates = [0.1, 0.15, 0.2] 
index = bisect.bisect(limits, sold) - 1 
if index >= 0: 
    rate = rates[index] 
else: 
    # sold is negative 

しかし、これはただのために少しoverengineeredようです3つの値...

編集:2番目の考えでは、最も読みやすい変形はおそらく

です
if sold >= 7700: 
    rate = 0.2 
elif sold >= 2000: 
    rate = 0.15 
elif sold >= 0: 
    rate = 0.1 
else: 
    # sold is negative 
+0

私はそれが好きです。なぜなら、境界線を使用する範囲にギャップがないので、はるかに簡単です。 –

+0

@HH:もちろん、これは私が 'bisect.bisect()'の意味です。そして例は*完全な例です。 –

+0

Sven Marnach:更新された質問のエラーを確認してください。 – hhh

1
if (sold >=0 & sold <7700): 

私は範囲をマップする本当に素晴らしい方法を認識していないんだけど、これはそれが非常に良く、少なくとも探します

if 0 <= sold < 7700: 

に相当します。

あなたも、あなたの第二のアプローチを使用することができます。

provisions = {(0, 2000) : 0.1, (2000,7700):0.15, (7700, float("inf")):0.20} 

# loop though the items and find the first that's in range 
for (lower, upper), rate in provisions.iteritems(): 
    if lower <= sold < upper: 
     break # `rate` remains set after the loop .. 

# which pretty similar (see comments) to 
rate = next(rate for (lower, upper), rate in 
       provisions.iteritems() if lower <= sold < upper)  
+0

'for'ループと' next() '呼び出しは、' sell'がどの区間にも含まれていない場合には等価ではありません。ループは自動的に最後のレートを返すでしょう。 'next()'は 'StopIteration'を送出します。後者が好ましいと思われる。 –

+0

@Sven Marnach:そうですが、少なくともinfの数字はすべてこのケースでカバーされていると思います。しかし、それは間違いなく心に留めておくべきことです。 –

+0

'else:raise StopIteration'をループに追加すると、両方のapporaches *が本当に同等になります(' lower'と 'upper'を現在のスコープに漏らすことを除いて)。 –

関連する問題