if 문 없는 파이썬 코드 작성하기

우연히 Medium에서 _Coding Tip: Try to Code Without If-statements - samerbina_을 접하게 되면서 교내 학식 크롤러 ‘jejunuMeals‘를 if문 없이 새로 작성해봤습니다.

딕셔너리를 사용하여 줄여보자

if문으로 제어하는 weekday , atom 을 딕셔너리 구조로 대체한다면 코드를 상당히 절약할 수 있을 것 같았다.

for index, atom in enumerate(data):
            if index == 1 or index == 5 or index == 9 or index == 13 or index == 17:
                weekday = weekday + 1
                yaml[weekday]['점심'][atom['정식'] = atom[2]
                yaml[weekday]['저녁'][atom['정식']] = atom[3]
            elif index == 2 or index == 6 or index == 10 or index == 14 or index == 18:
                yaml[weekday]['점심'][atom['특식']] = atom[1]
                yaml[weekday]['저녁'][atom['특식']] = atom[2]
            elif index == 3 or index == 7 or index == 11 or index == 15 or index == 19:
                yaml[weekday]['점심'][atom['양식']] = atom[1]
                yaml[weekday]['저녁'][atom['양식']] = atom[2]
            elif index == 4 or index == 8 or index == 12 or index == 16 or index == 20:
                yaml[weekday]['점심'][atom['중식']] = atom[1]
                yaml[weekday]['저녁'][atom['중식']] = atom[2]
return toYaml

여러 키에 같은 값을 대입하기

flags = {(1, 5, 9, 13): 2} # 처음에 생각했던 방법인데 안됨
flags = dict.fromkey([1, 5, 9, 13], 2) # 되지만 각각의 키들의 값이 동알한 메모리를 참조함
flags = {k:2 for v in [1, 4, 9, 13]} # 컴프리헨션으로 각자 다른  참조 가능

flags 딕셔너리로 atom 을 제어하기 위해 여러 키에 같은 값을 대입하는 방법을 생각해봤다.

dict.fromkey()는 각각의 키들이 동일한 메모리를 공유하는 문제가 있어서 컴프리헨션으로 처리했다.

weekdays = {0: 0, 1: 0, 2: 0, 3: 0, # 키가 많은 경우 하드코딩하자
            4: 1, 5: 1, 6: 1, 7: 1,
            8: 2, 9: 2, 10: 2, 11: 2,
            12: 3, 13: 3, 14: 3, 15: 3,
            16: 4, 17: 4, 18: 4, 19: 4}

weekdays 또한 딕셔너리를 정의해서 if 문이 필요 없게 만들었다.

결과

for index, atom in enumerate(data):
            weekday = weekdays[index]
            flag = flags.get(index, 1) # [1, 5, 9, 13] 외의 키는 1을 반환
            yaml[weekday]['점심'][atom[flag - 1]] = atom[flag]
            yaml[weekday]['저녁'][atom[flag - 1]] = atom[flag + 1]

'정식', '특식' '양식' '중식' 정보가 atom에 있어서 atom[flag - 1]로 바꿨다.