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

时间:2015-02-28 19:17:15

标签: python python-3.x

我正在尝试学习将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个分数外,该程序应该省略所有分数。

5 个答案:

答案 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"