[python] 등급 시스템 기능에서 반복적 인 if-elif 문을 어떻게 단순화 할 수 있습니까?

목표는 점수를 ‘0 to 1’시스템에서 ‘F to A’시스템으로 변환하는 프로그램을 구축하는 것입니다.

  • score >= 0.9‘A’를 인쇄 하면
  • score >= 0.8‘B’를 인쇄 하면
  • 0.7, C
  • 0.6, D
  • 그리고 그 지점보다 낮은 값은

이것은 그것을 빌드하는 방법이며 프로그램에서 작동하지만 다소 반복적입니다.

if scr >= 0.9:
    print('A')
elif scr >= 0.8:
    print('B')
elif scr >= 0.7:
    print('C')
elif scr >= 0.6:
    print('D')
else:
    print('F')

복합 명령문이 반복적이지 않도록 함수를 빌드하는 방법이 있는지 알고 싶습니다.

나는 완전한 초보자이지만 다음과 같은 내용이 있습니다.

def convertgrade(scr, numgrd, ltrgrd):
    if scr >= numgrd:
        return ltrgrd
    if scr < numgrd:
        return ltrgrd

가능합니까?

여기서 의도는 나중에 scr, numbergrade 및 letter grade 만 인수로 전달하여 호출 할 수 있다는 것입니다.

convertgrade(scr, 0.9, 'A')
convertgrade(scr, 0.8, 'B')
convertgrade(scr, 0.7, 'C')
convertgrade(scr, 0.6, 'D')
convertgrade(scr, 0.6, 'F')

더 적은 수의 인수를 전달할 수 있으면 더 좋습니다.



답변

bisect 모듈을 사용하여 숫자 테이블 조회를 수행 할 수 있습니다 .

from bisect import bisect

def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
     i = bisect(breakpoints, score)
     return grades[i]

>>> [grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']


답변

이 라인을 따라 무언가를 할 수 있습니다.

# if used repeatedly, it's better to declare outside of function and reuse
# grades = list(zip('ABCD', (.9, .8, .7, .6)))

def grade(score):
    grades = zip('ABCD', (.9, .8, .7, .6))
    return next((grade for grade, limit in grades if score >= limit), 'F')

>>> grade(1)
'A'
>>> grade(0.85)
'B'
>>> grade(0.55)
'F'

이것은 next에 의해 생성 된 점수 등급 쌍에 대해 생성기의 기본 인수와 함께 사용 됩니다 zip. 루프 접근 방식과 거의 동일합니다.


답변

각 등급에 임계 값을 할당 할 수 있습니다.

grades = {"A": 0.9, "B": 0.8, "C": 0.7, "D": 0.6, "E": 0.5}

def convert_grade(scr):
    for ltrgrd, numgrd in grades.items():
        if scr >= numgrd:
            return ltrgrd
    return "F"


답변

이 특정한 경우 외부 모듈이나 발전기가 필요하지 않습니다. 몇 가지 기본 수학으로 충분하고 빠릅니다!

grades = ["A", "B", "C", "D", "F"]

def convert_score(score):
    return grades[-max(int(score * 10) - 5, 0) - 1]

# Examples:
print(convert_grade(0.61)) # "D"
print(convert_grade(0.37)) # "F"
print(convert_grade(0.94)) # "A"


답변

np.select여러 조건에 대해 numpy 라이브러리에서 사용할 수 있습니다 .

>> x = np.array([0.9,0.8,0.7,0.6,0.5])

>> conditions  = [ x >= 0.9,  x >= 0.8, x >= 0.7, x >= 0.6]
>> choices     = ['A','B','C','D']

>> np.select(conditions, choices, default='F')
>> array(['A', 'B', 'C', 'D', 'F'], dtype='<U1')


답변

이 문제를 해결하는 간단한 아이디어가 있습니다.

def convert_grade(numgrd):
    number = min(9, int(numgrd * 10))
    number = number if number >= 6 else 4
    return chr(74 - number)

지금,

print(convert_grade(.95))  # --> A 
print(convert_grade(.9))  # --> A
print(convert_grade(.4))  # --> F
print(convert_grade(.2))  # --> F


답변

를 사용 numpy.searchsorted하면 한 번의 호출로 여러 점수를 처리 할 수있는 다음과 같은 멋진 옵션을 추가로 사용할 수 있습니다 .

import numpy as np

grades = np.array(['F', 'D', 'C', 'B', 'A'])
thresholds = np.arange(0.6, 1, 0.1)

scores = np.array([0.75, 0.83, 0.34, 0.9])
grades[np.searchsorted(thresholds, scores)]  # output: ['C', 'B', 'F', 'A']