在迭代时将键添加到int的defaultdict

时间:2018-09-03 11:15:44

标签: python csv dictionary defaultdict

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

我似乎无法弄清楚如何执行此步骤。我用打印语句检查了代码的大部分内容,看来字典工作正常,但是没有打印最后一支队伍,而是得分(Grouches,0分)。

我目前正在获得以下输出:

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

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:0)

您尝试过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))

答案 1 :(得分:0)

为达到目标而做得很好。您已经成功实现了逻辑,但是陷入了defaultdict的特定行为。有两点要注意:

  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

答案 2 :(得分:0)

添加CSV时代码破裂。 CSV阅读器为您执行01:30:31 [echoproperties] #Ant properties 01:30:31 [echoproperties] #Fri Aug 31 01:30:32 CEST 2018 01:30:31 [echoproperties] env.mgr.target.user=**** 。因此,您的mgr.target.usersplit(',')

因此您的代码更改为类似的

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]