Оптимизация кода решенной задачи по Python
Я начинающий программист. Прохожу курс. Решил задачу в рамках курса, но хочу сделать свое решение более красивым и оптимальным. Как можно улучшить и упростить мой код?
Задача:
На вход подается число n и потом n строк такого формата: 'Зенит;3;Спартак;1' Нужно написать программу, которая подсчитывает результаты всех матчей и выводит результат в таком формате:
Команда:Всего_игр Побед Ничьих Поражений Всего_очков
Мое решение:
n = int(input())
x = [input().split(';') for i in range(n)]
res = {}
g = 1
wp = 3
for i in x:
if int(i[1]) > int(i[3]):
if i[0] in res:
z = res.get(i[0])
z[0] += g
z[1] += g
z[4] += wp
else:
res[i[0]] = [1, 1, 0, 0, 3]
if i[2] in res:
z = res.get(i[2])
z[0] += g
z[3] += g
else:
res[i[2]] = [1, 0, 0, 1, 0]
if int(i[1]) < int(i[3]):
if i[2] in res:
z = res.get(i[2])
z[0] += g
z[1] += g
z[4] += wp
else:
res[i[2]] = [1, 1, 0, 0, 3]
if i[0] in res:
z = res.get(i[0])
z[0] += g
z[3] += g
else:
res[i[0]] = [1, 0, 0, 1, 0]
if int(i[1]) == int(i[3]):
if i[0] in res:
z = res.get(i[0])
z[0] += g
z[2] += g
z[4] += g
else:
res[i[0]] = [1, 0, 1, 0, 1]
if i[2] in res:
z = res.get(i[2])
z[0] += g
z[2] += g
z[4] += g
else:
res[i[2]] = [1, 0, 1, 0, 1]
for i in res:
print(i, ' '.join(map(str, res.get(i))), sep=':')
Спасибо за внимание!
Ответы (3 шт):
Разумно ввести функции и структуры данных. Посмотрите вот такой вариант.
game_result={
'WIN':3,
'LOSE':0,
'DRAW':1
}
def get_result(a):
if a[1]>a[3]:
return 'WIN','LOSE'
if a[1]==a[3]:
return 'DRAW','DRAW'
if a[1]<a[3]:
return 'LOSE','WIN'
n = int(input())
lst = [input().split(';') for i in range(n)]
res = {}
data={'games':1, 'WIN':0,'DRAW':0,'LOSE':0,'score':0}
for x in lst:
r1,r2=get_result(x)
if x[0] not in res.keys():
res[x[0]]=data.copy()
else:
res[x[0]]['games']+=1
if x[2] not in res.keys():
res[x[2]]=data.copy()
else:
res[x[2]]['games']+=1
res[x[0]][r1]+=1
res[x[0]]['score']+=game_result[r1]
res[x[2]][r2]+=1
res[x[2]]['score']+=game_result[r2]
for x in res:
print(x,res[x])
Чтоб убрать if i[0] in res: else: используйте defaultdict
res=defaultdict(lambda: list((0,0,0,0)))
В выводе можно убрать get и map.
for k, v in result.items():
print(k, end=": ")
print(*v, sep=' ')
if < , if >, if == можно исправить на if, elif, else
На основе идей @becouse. Надеюсь в более идеоматичном стиле. Требуется python 3.7
from dataclasses import dataclass
from collections import defaultdict
@dataclass
class Results:
games: int = 0
win: int = 0
draw: int = 0
lose: int = 0
def add_match(self, result):
self.games += 1
value = getattr(self, result)
setattr(self, result, value + 1)
@property
def points(self):
return self.win*3 + self.draw*1
def __repr__(self):
return f'{self.games}, {self.win}, {self.draw}, {self.lose}, {self.points}'
def get_result(score):
first, second = score
if first > second:
return 'win', 'lose'
elif first == second:
return 'draw', 'draw'
else:
return 'lose', 'win'
#n = int(input())
#matches = [input().split(';') for i in range(n)]
matches = [['Зенит', 3, 'Спартак', 1], ['Зенит', 1, 'Динамо', 2]]
results = defaultdict(Results)
for match in matches:
teams = match[::2]
score = match[1::2]
for team, result in zip(teams, get_result(score)):
results[team].add_match(result)
for k, v in results.items():
print(k, v)
Зенит 2, 1, 0, 1, 3
Спартак 1, 0, 0, 1, 0
Динамо 1, 1, 0, 0, 3