迭代时将键添加到 int 的 defaultdict

Adding keys to defaultdict of int while iterating

脚本需要从 text/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

我似乎无法弄清楚如何进行这一步。我用打印语句检查了大部分代码,字典似乎工作正常,但它没有打印最后一支球队和它的分数(抱怨,0 分)。

我目前得到这个输出:

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

如有任何帮助,我们将不胜感激!

您尝试过 CSV python 库吗?摘自文档 (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))

走到这一步做得很好。您已经设法实现了逻辑,但被 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-strings(后者在 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

添加 CSV 时的代码中断。 CSV reader 为您完成 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()]