Добавление ключей к defaultdict из int во время итерации - PullRequest
0 голосов
/ 03 сентября 2018

Сценарий должен прочитать входные данные из текстового / CSV-файла, но как только я пытаюсь реализовать эту функциональность, все ломается.

Вот мой код:

from collections import defaultdict
#from csv import reader

data = """Lions 3, Snakes 3
Tarantulas 1, FC Awesome 0
Lions 1, FC Awesome 1
Tarantulas 3, Snakes 1
Lions 4, Grouches 0"""

# with open('sample_input.csv') as data:
#     csv = reader(data)
#     list_csv = [line.rstrip('\n') for line in data]

data_list = data.splitlines()


def splitter(row):
    left_team, right_team = row.split(',')
    return {
        'left': left_team[:-2].strip(),
        'left_score': int(left_team[-2:].strip()),
        'right': right_team[:-2].strip(),
        'right_score': int(right_team[-2:].strip())
    }


data_dicts = [splitter(row) for row in data_list]


team_scores = defaultdict(int)
for game in data_dicts:
    if game['left_score'] == game['right_score']:
        team_scores[game['left']] += 1
        team_scores[game['right']] += 1
    elif game ['left_score'] > game['right_score']:
        team_scores[game['left']] += 3
    else:
        team_scores[game['right']] += 3
    print(team_scores)

teams_sorted = sorted(team_scores.items(), key=lambda team: team[1], reverse=True)


# for line in teams_sorted:
#     print(line)

Кроме того, ожидаемый результат, который мне нужен:

1. Tarantulas, 6 pts
2. Lions, 5 pts
3. FC Awesome, 1 pt
3. Snakes, 1 pt
4. Grouches, 0 pts

Я просто не могу понять, как добраться до этого шага. Я проверил большинство частей моего кода с помощью операторов print, и кажется, что словарь работает правильно, но он не печатает последнюю команду и ее результаты (Grouches, 0 pts).

В настоящее время я получаю этот вывод:

('Tarantulas', 6)
('Lions', 5)
('Snakes', 1)
('FC Awesome', 1)

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

0 голосов
/ 03 сентября 2018

Молодец, что зашел так далеко. Вам удалось реализовать логику, но вы застряли с определенным поведением defaultdict. Следует отметить 2 основных момента:

  1. Если ключ не инициализирован с defaultdict, он не будет добавлен в словарь. Вы можете сделать это, просто добавив 0 к неинициализированному ключу.
  2. Для конкретного требуемого форматирования вы можете использовать enumerate в цикле после сортировки.

Соединяя их, измените ваш цикл следующим образом:

for game in data_dicts:
    if game['left_score'] == game['right_score']:
        team_scores[game['left']] += 1
        team_scores[game['right']] += 1
    elif game ['left_score'] > game['right_score']:
        team_scores[game['left']] += 3
        team_scores[game['right']] += 0
    else:
        team_scores[game['left']] += 0
        team_scores[game['right']] += 3

Затем используйте enumerate в цикле. Вы можете использовать operator.itemgetter и f-строки (последние в Python 3.6+), чтобы сделать вашу логику чище:

from operator import itemgetter

teams_sorted = sorted(team_scores.items(), key=itemgetter(1), reverse=True)

for idx, (team, score) in enumerate(teams_sorted, 1):
    print(f'{idx}. {team} {score} pts')

1. Tarantulas 6 pts
2. Lions 5 pts
3. Snakes 1 pts
4. FC Awesome 1 pts
5. Grouches 0 pts
0 голосов
/ 03 сентября 2018

к коду, ломающемуся при добавлении CSV. Читатель CSV делает split(',') для вас. Так что ваши left_team = row[0] и right_team = row[1]

Таким образом, ваш код меняется на что-то вроде

def spliter(row):
    left_team, right_team = row
    return {
        'left': left_team[:-2].strip(),
        'left_score': int(left_team[-2:].strip()),
        'right': right_team[:-2].strip(),
        'right_score': int(right_team[-2:].strip())
    }

with open('data.csv') as data_obj:
    reader = csv.reader(data_obj)
    data_dicts = [splitter(row) for row in reader]

Вы можете перейти к чтению открытого текста, если хотите вручную split(',').

with open('data.csv') as data_obj:
    data_list = [line.rstrip('\n') for line in data_obj.readlines()]
0 голосов
/ 03 сентября 2018

вы пробовали CSV python lib? Извлечено из документа (https://docs.python.org/3/library/csv.html):

import csv
with open('data.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in spamreader:
        print(', '.join(row))
...