【问题标题】:Maximum pieces of data appending to a file附加到文件的最大数据条数
【发布时间】:2014-02-17 23:11:35
【问题描述】:

我有一段代码将用户名和分数附加到文件中,但我想知道如何才能使文件中随时只有 10 个名称和分数。我的代码如下:

def storescores():
    hs = open("hst.txt", "a")
    hs.write(name + " ")
    hs.write(str(score) + "\n")
    hs.close()

有没有什么办法可以做到如果名单上已经有 10 个名字就不能再添加了?如果这需要某种形式的排序方法(选择、冒泡等),那么您能否将其也放入其中?

【问题讨论】:

  • 您只想要 top 10 个分数吗?还是只有最近的 10 家商店?还是只有 10个分数?
  • 如果“只有前10名”的意思是如果我打了一个分数然后删除最低的分数并添加新的分数,那么是的,如果不是太麻烦的话

标签: python sorting file-io max


【解决方案1】:

首先,无论您做什么,都需要从文件中读取最多 10 行。

如果您只想保留前 10 个分数,然后停止记录新的分数,这很容易。我将使用linecache 模块来提高效率(因此,如果您连续调用storescores 1000 次,它会记住它已经在寻找但未能找到第10 行)。如果少于 10 行,这将返回一个空字符串,如果有 10 行或更多,则返回第 10 行。所以:

def storescores():
    if linecache.getline("hst.txt", 10):
        print("Already stored 10 scores, sorry")
        return
    hs.close()
    hs = open("hst.txt", "a")
    hs.write(name + " ")
    hs.write(str(score) + "\n")
    hs.close()

如果你想要最近的 10 个分数,你必须读入这些行,然后写出一个新文件。像这样:

def storescores():
    with open("hst.txt") as hs:
        lines = list(hs)
    lines.append(name + " " + score + "\n")
    lines = lines[-10:]
    with open("hst.txt", "w") as hs:
        for line in lines:
            hs.write(line)

如果你想要 top 10 的分数,你可以做同样的事情,但在中间添加一个排序步骤。没有理由编写显式选择排序或冒泡排序——事实上,您也不想这样做,因为这些排序算法本来就不是好的排序算法。只需在列表上调用sort 方法即可。

棘手的一点是您要按 score 排序,而不是整行(否则“Bob 100”的分数高于“Andrew 200”),并且按分数 作为数字而不是作为字符串(否则,“2”的分数高于“10”)。因此,您需要一个 key function 来拆分字符串,获取最后一位并将其转换为数字。所以:

def storescores():
    with open("hst.txt") as hs:
        lines = list(hs)
    lines.append(name + " " + score + "\n")
    lines.sort(key=lambda line: int(line.split()[-1]))
    lines = lines[-10:]
    with open("hst.txt", "w") as hs:
        for line in lines:
            hs.write(line)

有一些方法可以进一步改进这一点。例如,您可能希望写入一个新的临时文件,而不是就地重写文件,然后在完成后将其复制到文件上(因此,如果有人在您的程序运行中间拔掉了插件,您最终得到旧分数或新分数,而不是截断的部分文件)。或者您可能想以最聪明的方式使用heapqbisect 模块将新分数放到适当的排序位置,而不是重新排序整个已排序的列表(当只有 10 个时,这并不重要条目)。等等。但这应该足以让您入门。

【讨论】:

  • 谢谢,第三个是我要找的,但是它把最小的分数放在第一位,有没有办法把最高分放在第一位? (例如,当我更喜欢 [18, 11, 2] 时,列表按 [2, 11, 18] 的顺序排列)
  • @user3320839:当然。简短的版本是,使用reverse 参数到sort。但是你真的应该阅读我链接的排序指南并了解你可以做的所有事情。 (请注意,如果您颠倒顺序,您还需要保留前 10 个:lines[:10],而不是最后 10 个,lines[-10:]。)
  • 谢谢,我会为该页面添加书签。如果我想在程序中写出各个排序方法的代码,你知道在哪里可以找到一个页面吗?
  • @user3320839:你的意思是list.sort的源代码?在 CPython 中,这是用 C 编写的;您可能需要先阅读listsort.txt,然后再阅读the C codesorted 函数和大多数其他内置排序相关的东西(甚至只是像itertools.groupby 这样的外围相关的东西)的情况相似。但是,您可能想查看 PyPy,它对大多数事物都有纯 Python 实现。
  • @user3320839:PyPy 搜索起来可能有点复杂; list.sort 不是很有用,直到你通过 5 个步骤追踪到 TimSort...
【解决方案2】:

没有内置的方法可以做这样的事情。你需要做的是类似

  1. 读入文件
  2. 添加最新分数
  3. 检查列表,看看分数是否太多,如果有,删除一个
  4. 写入文件

【讨论】:

    猜你喜欢
    • 2014-07-27
    • 2022-08-14
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多