【问题标题】:Sorting strings with integers and text in Python在 Python 中使用整数和文本对字符串进行排序
【发布时间】:2025-12-01 05:00:01
【问题描述】:

我正在制作一个愚蠢的小游戏,它将您的分数保存在 highscores.txt 文件中。

我的问题是对行进行排序。这是我到目前为止所拥有的。

也许python的字母数字排序器会有所帮助?谢谢。

import os.path
import string

def main():
    #Check if the file exists
    file_exists = os.path.exists("highscores.txt")

    score = 500
    name = "Nicholas"

    #If the file doesn't exist, create one with the high scores format.
    if file_exists == False:
        f = open("highscores.txt", "w")
        f.write('Guppies High Scores\n1000..........Name\n750..........Name\n600..........Name\n450..........Name\n300..........Name')

    new_score = str(score) + ".........." + name

    f = open("highscores.txt", "r+")
    words = f.readlines()
    print words

main()

【问题讨论】:

    标签: python string alphanumeric


    【解决方案1】:

    words = f.readlines() 之后,尝试类似:

    headers = words.pop(0)
    
    def myway(aline):
      i = 0
      while aline[i].isdigit():
        i += 1
      score = int(aline[:i])
      return score
    
    words.sort(key=myway, reverse=True)
    
    words.insert(0, headers)
    

    关键(;-)的想法是创建一个函数,从每个项目(这里是一行)返回“排序键”。我正在尝试以最简单的方式编写它:查看有多少个前导数字,然后将它们全部转换为 int,然后返回。

    【讨论】:

    • 谢谢亚历克斯!但是当我在我的代码中插入它时,我收到一个错误:SyntaxError: Non-ASCII character '\xc2' in file read.py on line 24, but no encoding declaration;有关详细信息,请参阅python.org/peps/pep-0263.html 有什么想法吗?再次感谢!
    • @Nicholas,我发布的代码中没有非 ASCII 文本(特别是没有 0xc2 -- 在 Latin-1 中,这将是带有抑扬符的大写字母 A),并且所以当然我完全不知道你是如何设法让一个进入 your 代码的。如果您无法在自己的代码中发现它(?!),也许可以在问题中发布该代码 - 但这与 this 问题的关系确实为零,我似乎已经令人满意地回答了这个问题,所以我建议你把它作为一个单独的问题。
    【解决方案2】:

    我想鼓励您以更强大的格式存储您的高分。我特别建议使用 JSON。

    import simplejson as json  # Python 2.x
    # import json  # Python 3.x
    
    d = {}
    d["version"] = 1
    d["highscores"] = [[100, "Steve"], [200, "Ken"], [400, "Denise"]]
    s = json.dumps(d)
    print s
    # prints:
    # {"version": 1, "highscores": [[100, "Steve"], [200, "Ken"], [400, "Denise"]]}
    
    
    d2 = json.loads(s)
    for score, name in sorted(d2["highscores"], reverse=True):
        print "%5d\t%s" % (score, name)
    
    # prints:
    #  400  Denise
    #  200  Ken
    #  100  Steve
    

    使用 JSON 将使您不必编写自己的解析器来从保存的文件(例如高分表)中恢复数据。你可以把所有的东西都塞进字典里,然后轻而易举地把它全部找回来。

    请注意,我添加了一个版本号,即您的高分保存格式的版本号。如果您更改了数据的保存格式,其中有一个版本号将是一件非常好的事情。

    【讨论】:

    • +1: 或 yaml,如果您希望它更易于阅读(并且不需要通过网络发送)
    • 或者你可以是传统的并使用 Python pickle 模块。这可以保存任何 Python 数据类型,并且它包含在每个 Python 安装中。虽然不是很可读。
    【解决方案3】:

    我猜你粘贴 Alex 的答案时出了点问题,所以这是你的代码,里面有一个排序

    
    import os.path
    
    def main():
        #Check if the file exists
        file_exists = os.path.exists("highscores.txt")
    
        score = 500
        name = "Nicholas"
    
        #If the file doesn't exist, create one with the high scores format.
        if file_exists == False:
            f = open("highscores.txt", "w")
            f.write('Guppies High Scores\n1000..........Name\n750..........Name\n600..........Name\n450..........Name\n300..........Name')
    
        new_score = str(score) + ".........." + name +"\n"
    
        f = open("highscores.txt", "r+")
        words = f.readlines()
    
        headers = words.pop(0)
    
        def anotherway(aline):
          score="" 
          for c in aline:
              if c.isdigit():
                  score+=c
              else:
                  break
          return int(score)
    
        words.append(new_score)
        words.sort(key=anotherway, reverse=True)
    
        words.insert(0, headers)
    
        print "".join(words)
    
    main()
    

    【讨论】:

      【解决方案4】:

      您想要的可能是通常所说的“自然排序”。搜索“natural sort python”会得到很多结果,但在ASPN 上有一些很好的讨论。

      【讨论】:

        【解决方案5】:

        在你的

        上做一个简单的字符串排序
        new_score = str(score) + ".........." + name
        

        items 不会工作,因为例如 str(1000)

        Alex 的回答很好,因为它演示了排序键功能的使用,但这是另一种解决方案,它更简单一些,并且具有在视觉上对齐高分显示的额外优势。

        您需要做的是将您的数字右对齐在分数的最大大小的固定字段中,因此(假设最大 5 位和ver

        new_score = "%5d........%s" % (score, name)
        

        或者对于 Python 3.x 版:

        new_score = "{0:5d}........{1}".format(score, name)
        

        对于每个 new_score 将其附加到单词列表(您可以在此处使用更好的名称)并在打印前对其进行倒序排序。或者你可以使用 bisect.insort 库函数而不是 list.append。

        另外,比

        更Pythonic的形式
        if file_exists == False:
        

        是:

        if not file_exists:
        

        【讨论】:

          最近更新 更多