我正在尝试学习将Python用于个人项目的基础知识。
我创建了一个程序,向用户询问了10个地理问题,然后将其分数保存为.txt文件,格式如下:
Imran - 8
Joeseph - 10
Test1 - 6
Test2 - 4
Joeseph - 5
Aaron - 4
Test1 - 1
Zzron - 1
Joeseph - 3
Test1 - 10
Joeseph - 4
然后我创建了一个新程序,可用于按字母顺序显示每个人的最高分数:
with open("highscores.txt", "r+")as file:
file.seek(0)
scores = file.readlines()
user_scores = {}
for line in scores:
name, score = line.rstrip('\n').split(' - ')
score = int(score)
if name not in user_scores or user_scores[name] < score:
user_scores[name] = score
for name in sorted(user_scores):
print(name, '-', user_scores[name])
我想改变这段代码,这样它只输出一个人最高的3个最近的分数。例如,根据给出的.txt文件,Joeseph的得分将显示为:
Joeseph - 5
除了每个人最近的3个分数外,该程序应该省略所有分数。
答案 0 :(得分:2)
这应该可以解决问题
from collections import defaultdict, deque
with open("highscores.txt", "r+")as file:
file.seek(0)
scores = file.readlines()
user_scores = defaultdict(lambda:deque(maxlen=3))
for line in scores:
name, score = line.rstrip('\n').split(' - ')
score = int(score)
user_scores[name].append(score)
for name in user_scores:
print(name, '-', max(user_scores[name]))
通过使用defaultdict,我们避免了检查中的丑陋。 deque仅保留最后3个分数。请注意,即使用户的得分低于3分,这也有效。
如果您需要排序的高分,那么最后一个循环可以替换为:
user_scores=[(max(user_scores[user]), user) for user in user_scores]
for score, name in sorted(user_scores):
print(name, '-', score)
答案 1 :(得分:1)
不要跟踪你的第一个for循环中的最高分,而是跟踪最后三个分数:
user_scores = {}
for line in scores:
name, score = line.rstrip('\n').split(' - ')
score = int(score)
if name not in user_scores:
user_scores[name] = [] # Initialize score list
user_scores[name].append(score) # Add the most recent score
if len(user_scores[name]) > 3:
user_scores[name].pop(0) # If we've stored more than 3, get rid of the oldest
然后在最后,通过并获得最大值:
user_high_scores = {}
for name in user_scores:
user_high_scores[name] = max(user_scores[name]) # Find the highest of the 3 most recent scores
然后你可以像以前一样打印出高分:
for name in sorted(user_scores):
print(name, '-', user_scores[name])
答案 2 :(得分:1)
首先,由于您只想阅读最后3个分数,请从文件末尾开始并向后阅读。
user_scores = {}
for line in reversed(open("scores.txt").readlines()):
name, score = line.rstrip('\n').split(' - ')
score = int(score)
# first, only update if the name exists
# and there is less than 3 scores already
if name in user_scores and len(user_scores[name]) < 3:
user_scores[name].append(score)
# this is a new record, so lets just add it
# make the value a list so we can easily just add a score to it
if name not in user_scores:
user_scores[name] = list((score,))
现在我们有一个用户的词典,每个用户都有一个最近3个得分的列表。让我们得到他们的最高分。
best_scores = {}
for name in sorted(user_scores):
# get the highest score in the list.
best_scores[name] = max(user_scores[name])
现在,我们可以根据需要简单地打印出用户的最高分数
for name in sorted(best_scores):
print("{} - {}".format(name, best_scores[name]))
答案 3 :(得分:0)
如果我理解你的话,输出应该是:
Joeseph - 5
Joeseph - 3
Joeseph - 4
这就是我解决问题的方法
with open("highscores.txt", "r+") as file:
file.seek(0)
scores = file.readlines()
# generate list of [name, score] pairs instead of strings
scores_pairs = [score.strip().split(' - ') for score in scores]
# configure output
lookup_name = 'Joeseph'
RECENT_SCORES_LIMIT = 3
# indicates how many scores were added
recent_scores_count = 0
# scores will be stored here
most_recent_scores = []
# we need to reverse list to search it from the end
for score in reversed(scores_pairs):
name = score[0]
# if current score is if interested person and scores limit not exceeded...
if name == lookup_name and recent_scores_count < RECENT_SCORES_LIMIT:
# add current score to list
most_recent_scores.append(score)
recent_scores_count += 1
# to display scores in historical order we need to reverse list again
for name, score in reversed(most_recent_scores):
# better use .format method to produce strings using python variables
print('{} - {}'.format(name, score))
答案 4 :(得分:-1)
通常的方法是使用collections.deque
from collections import defaultdict, deque
d = defaultdict(lambda: deque(maxlen=3))
# some dict d where d['new key'] -> d['new key'] = deque(maxlen=3)
with open('path/to/scores.txt') as scores:
for line in scores:
name, score = line.split(" - ")
d[name].append(int(score))
for player, scores in sorted(d.items()):
print("{} - {}".format(player, max(scores))
# {"James":deque([2,6,11]), -> "James - 11"
# {"Susan":deque([3,1,2])} -> "Susan - 3"