Python:从文件中搜索,获得最大数量

时间:2015-04-27 07:38:39

标签: python

因此,该计划必须找到每个级别得分最高的玩家。 我有一个名为 public Form1() { InitializeComponent(); try { foreach (Button b in Controls) { FillBoard(b); } Label tScore = new Label(); tScore.Size = new Size(244, 22); tScore.Location = new Point(12, 46); tScore.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); tScore.Text = "Some text"; tScore.Visible = true; Controls.Add(tScore); Show(); Refresh(); } catch { } } 的文本文件,其中包含每行的名称,分数和级别。格式为playerScores.txt的示例:

Player:Level:Score

该计划必须找到每个级别的最高得分者,因此对于级别1,它必须找到最高的数字。这是我到目前为止所得到的:

Starplayer,1,19

这会找到每个级别的第二个逗号之后的数字,但它会找到所有数字而不只是最高的数字。

3 个答案:

答案 0 :(得分:1)

您需要做的第一件事是将分数从字符串转换为数字。像这样:

for line in playerData: 
    sname, slevel, sscore = line.split(",")
    sscore = int(sscore)

请注意,我也只调用了split一次而不是3次,并为结果提供了有意义的名称,而不是仅仅调用它们[1]等等。

如果您使用的是Python 2.x,则level = input("Game Level?")会将您的输入转换为int,因此您需要转换每个slevelint也是如此。但是,你真的,真的,不应该在Python 2.x中使用input;更好的解决方法是将其切换为raw_input。但是你可能想要转换为int,所以如果有人输入"我不知道该把什么放在这里"他们得到错误而不是没有结果。 :)所以,让我们说明:

level = int(raw_input("Game Level?")) # asking for which level

(如果您实际使用的是Python 3.x,请将raw_input保留为input,但仍然会在其周围添加int。)

然后,在循环中:

    sname, slevel, sscore = line.split(",")
    slevel = int(slevel)
    sscore = int(sscore)

接下来,您可以随时跟踪最高数字:

hsname, hslevel, hsscore = None, None, -1
for line in playerData: 
    sname, slevel, sscore = line.split(",")
    slevel = int(slevel)
    if slevel == level:
        sscore = int(sscore)
        if sscore > hsscore:
            hsname, hslevel, hsscore = sname, slevel, sscore

然后你最后将它打印出来:

print(hslevel)
print(hsname)
print(hsscore)

如果你想变得聪明,可以通过将可迭代的行转换为可迭代的三元组,然后在结果上调用max来实现:

triples = (line.strip().split(",") for line in playerData)
level_triples = ((n, l, s) for (n, l, s) in triples if int(l) == level)
highscore = max(triples, key=lambda triple: int(triple[2]))
hsname, hslevel, hsscore = highscore

无论哪种方式,我们都不会存储除目前为止所见的最高分的名称/等级/分数以外的任何内容。 (在第一个版本中,这是明确的;在第二个版本中,我们只是构建惰性迭代器并调用max,因此它会隐式发生。)如果你真的只是想要进行一次查找然后退出。

但是,如果您要进行多次查找 - 比如说,您希望有一个菜单,用户可以逐级询问,或者您只想打印出所有级别'高分 - 您可以更好地将数据转换为易于进行查找的格式,如Kasra's answer中所示。

答案 1 :(得分:1)

您可以使用collections.defaultdict执行此类任务:

from collections import defaultdict
d=defaultdict(list)
playerData = open("playerScores.txt", "r") #opening file with data
level = input("Game Level?") # asking for which level
for line in playerData:
    l=line.split(",") 
    if(l[1] == level):
            d[l[1]].append(int(l[2]))
for i,j in d.items():
   print 'level{}:{}'.format(i,max(j))

在前面的代码中,您循环分割线并将级别存储为词典的键,并将相关分数附加到其list的值。

在字典上创建字典循环并打印分数的levelmax后。

或者您可以使用dict.setdefault方法:

d={}
playerData = open("playerScores.txt", "r") #opening file with data
level = input("Game Level?") # asking for which level
for line in playerData:
    l=line.split(",") 
    if(l[1] == level):
            d.setdefault(l[1],[]).append(int(l[2]))
for i,j in d.items():
   print 'level{}:{}'.format(i,max(j))

另外,作为一种更有效的方法,您可以使用csv模块打开文件:

import csv
d={}
with open('eggs.csv', 'rb') as csvfile:
     spamreader = csv.reader(csvfile, delimiter=',')
     for row in spamreader:
        d.setdefault(row[1],[]).append(int(row[2]))

 for i,j in d.items():
     print 'level{}:{}'.format(i,max(j))

答案 2 :(得分:0)

尝试读取适当数据结构中的所有数据。然后你可以要求任何你想要的等级:

highscores = {}
with open("playerScores.txt", "r") as scores:
    for line in playerData:
        player, level, score = line.split(',')
        level = int(level)
        score = int(score)
        if level not in highscores or highscores[level][1] < score:
            highscores[level] = player, score

level = input("Game Level?") # asking for which level
print(highscores[int(level)])