12

私が書いたPythonコードのこの小さなスニペットがあります。うまくいきますが、同じ結果を得るにはもっと合理的な方法が必要だと思います。私はそれを見ていません。何か案は?

if tx_avt >= 100: tx = 1 
elif tx_avt < 100 and tx_avt >= 50: tx = 2 
elif tx_avt < 50 and tx_avt >= 25: tx = 3
elif tx_avt < 25 and tx_avt >= 12.5: tx = 4 
else: tx = 5
4

5 に答える 5

29

次のように変更できます。

if tx_avt >= 100: tx = 1 
elif tx_avt >= 50: tx = 2 
elif tx_avt >= 25: tx = 3
elif tx_avt >= 12.5: tx = 4 
else: tx = 5

説明:

  • 真でない場合は、それが真でなければならないif tx_avt >= 100ことを推測できます。tx_avt < 100
  • tx_avt < 100これにより、チェック「 」の「」部分を実行する必要がなくなりelif tx_avt < 100 and tx_avt >= 50:ます。

同じロジックがカスケードされ、残りのelifケースに適用されます。


関連資料:PythonにSwitchステートメントがない理由とその代替案

于 2012-11-27T17:34:11.897 に答える
10

これらは上の句によって解決されるため、elifの上限は必要ありません...

elif tx_avt >= 50 : #do something
elif tx_avt >= 25 : #somthing else

pythonでの補足として、あなたができること

if 3 < ab < 10 : #check if ab is between 3 and 10
于 2012-11-27T17:34:45.427 に答える
8

if-elif-else チェーンが非常に長くなる場合は、次の方法を使用できます。

for amt, tx in [(100, 1), (50, 2), (25, 3), (12.5, 4)]:
    if tx_avt >= amt:
        break
else:
    tx = 5

注:ループのelse句は、検出されない場合に実行されます。この場合、デフォルトのケースを提供するために使用されます。forbreak

于 2012-11-27T17:36:07.303 に答える
3

別の考えを与えるために、これは bisect モジュールのバイナリ検索機能を使用してワンライナーで行うことができます。

In [106]: def index(a,x):
   .....:         return len(a) - bisect.bisect_right(a, x) + 1
   .....:

In [107]: a=[12.5,25,50,100]

In [108]: index(a,15)
Out[108]: 4

In [109]: index(a,25)
Out[109]: 3

In [110]: index(a,35)
Out[110]: 3

In [111]: index(a,50)
Out[111]: 2

In [112]: index(a,100)
Out[112]: 1
于 2012-11-27T18:53:13.167 に答える
0

[12.5, 25, 50, 100] が系列であるという事実に基づくさらに別のアイデア:

MAX_BOUNDARY = 5
for tx, boundary in [(n, 25 * 2**(-n+3)) for n in range(1, MAX_BOUNDARY)]:
    if tx_avt >= boundary:
        break
else:
    tx = MAX_BOUNDARY

(これはわずかに変更された @StevenRumbalski バージョンです)

bisectこれは、tx_avt の分布が均一 (wrt 系列関数) であり、リストが非常に大きくなる場合、O(log(n)) 検索に関する @WaiYipTung のアイデアと組み合わせることができます。

それ以外の場合は、@ JoranBeasley や @SampsonChen が提案するような、よりシンプルで理解しやすいソリューションに固執する必要があります。

于 2012-11-27T19:20:01.560 に答える