2011-01-25 3 views
0

이 질문을 Code Review -area으로 옮기십시오. 아래의 코드가 쓰레기라는 것을 알고 있기 때문에 필자는 재 작성을 완료하기 위해 중요한 피드백을 원했습니다.범위와 일부 상수 사이의 사적 관계?

어떻게 파이썬에서 상수 세트를 쓸 수 있습니까? 따라서 범위에 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

, 내가 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 보인다 세 값 ...

편집 : 두 번째 생각에 가장 읽을 수있는 변형은 아마도

입니다.
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'를 누설하는 것을 제외하고). –

관련 문제