
부제 :
ZeroDivisionError의 늪..
복서 선수들의 몸무게 weights와, 복서 선수들의 전적을 나타내는 head2head가 매개변수로 주어집니다. 복서 선수들의 번호를 다음과 같은 순서로 정렬한 후 return 하도록 solution 함수를 완성해주세요.
from collections import defaultdict
def solution(weights, head2head):
player = defaultdict(list)
for j,h in enumerate(zip(weights, head2head), start=1) :
ncnt = h[1].count("N")
if len(h[1])-ncnt != 0 :
player[j] = [h[0], h[1].count("W")/(len(h[1])-ncnt),0]
else :
player[j] = [h[0], 0, 0]
losers = list(map(lambda z : z+1, list(filter(lambda x: h[1][x] == "W", range(len(h[1]))))))
for loser in losers :
if player[j][0] < weights[loser-1] :
player[j][2] += 1
return sorted(player, key = lambda x : (-player[x][1], -player[x][2], -player[x][0], x))
다음의 과정에 따라 풀이하였다.
key Error를 방지하기위해 defaultdict로 선수번호 : [몸무게, 승률, 자신보다 몸무게가 무거운 복서를 이긴 횟수]를 담기위한 딕셔너리인 player를 생성한다from collections import defaultdict
...
player = defailtdoct(list)
j는 선수번호, h[0]은 몸무게, h[1] 은 각 선수가 치른 경기 결과, ncnt는 승률 계산을 위해 두 복서가 아직 싸우지 않은 경기를 카운트 한다. 선수 번호는 1번부터 시작하므로 start = 1을 준다.for j,h in enumerate(zip(weights, head2head), start=1) :
ncnt = h[1].count("N")
if len(h[1])-ncnt != 0 :
player[j] = [h[0], h[1].count("W")/(len(h[1])-ncnt),0]
else :
player[j] = [h[0], 0, 0]
여기서 ZeroDivisionError를 방지하기위해(선수들이 서로 모두 싸워보지 않은 경우) 조건문으로 나눠주었다.
filter로 인덱스 번호를 찾은 뒤 map 메서드로 +1씩 해준다 (인덱스는 0부터 시작하므로)losers = list(map(lambda z : z+1, list(filter(lambda x: h[1][x] == "W", range(len(h[1]))))))
for loser in losers :
if player[j][0] < weights[loser-1] :
player[j][2] += 1
return sorted(player, key = lambda x : (-player[x][1], -player[x][2], -player[x][0], x))

오늘의 교훈 : 난 항상 맞게 풀었다고 생각하지만, 실패는 괜히 뜨는게 아닌 법..