迭代时将键添加到 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点需要注意:
- 如果一个键没有用
defaultdict
初始化,它就不会被添加到字典中。您只需将 0 添加到未初始化的密钥即可。
- 对于您需要的特定格式,您可以在排序后循环使用
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()]
脚本需要从 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点需要注意:
- 如果一个键没有用
defaultdict
初始化,它就不会被添加到字典中。您只需将 0 添加到未初始化的密钥即可。 - 对于您需要的特定格式,您可以在排序后循环使用
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()]