仅显示一个人最近 3 个分数中的最高分数,保存在.txt文件中



我正在努力学习将Python用于个人项目的基本原理。

我创建了一个程序,向用户询问十个地理问题,然后将他们的分数保存到.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个最新分数外的所有分数。

与其跟踪第一个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])

这应该可以完成

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,我们避免了丑陋的检查。德克只保持最后3分。请注意,即使用户的分数低于3分,这也是有效的。

如果你需要对高分进行排序,那么最后一个循环可以替换为:

user_scores=[(max(user_scores[user]), user) for user in user_scores]
for score, name in sorted(user_scores):
    print(name, '-', score)

首先,由于您只想读取最后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,))

现在我们有一个用户的dict,每个用户都有一个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]))

如果我理解得对,输出应该是:

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))

通常的方法是使用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"

最新更新