2009-10-16 2 views
0

Я делаю глупую маленькую игру, которая сохраняет вашу оценку в файле highscores.txt.Сортировка строк с целыми числами и текстом в Python

Моя проблема заключается в сортировке строк. Вот что я до сих пор.

Может быть, поможет алфавитно-цифровой сортировщик для 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() 
+0

Попробуйте использовать массив –

ответ

4

после 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 и верните их.

+0

Спасибо Alex! Но когда я вставляю это в свой код, я получаю сообщение об ошибке: SyntaxError: не-ASCII-символ '\ xc2' в файле read.py в строке 24, но не объявлено кодирование; см. http://www.python.org/peps/pep-0263.html для получения более подробной информации. Любые идеи, из чего это происходит? Еще раз спасибо! – Nicholas

+0

@ Николас, в тексте кода, который я разместил, нет текста, отличного от ASCII (и, в частности, «0xc2» - в латинском-1, это будет верхний регистр-A с округлой линией), и, конечно, у меня абсолютно нет Идея, как вам удалось получить ее в свой код. Если вы не можете определить его в своем собственном коде (?!), Возможно, опубликуйте этот код в вопросе, но это действительно имеет нулевое отношение к _this_ вопросу, на который я, кажется, ответил удовлетворительно, поэтому я предлагаю вам сделать это a_separate_ вопрос. –

0

Выполнение простой строковый вид на ваших

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

пунктов не будет работать, так как, например, ул (1000) < ул (500). Другими словами, 1000 будет стоить до 500 в алфавитно-цифровой сортировке.

Ответ Алекса хорош тем, что он демонстрирует использование функции сортировки ключей, но вот другое решение, которое немного проще и обладает дополнительным преимуществом визуализации выравнивания дисплеев с высокой оценкой.

Что вам нужно сделать, это право выровнять числа в фиксированном поле максимального размера баллов, таким образом (предполагается, что 5 цифр макс и вер < 3,0):

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: 
0

Я думаю, что-то пошло не так, когда вы вставили от ответа Алекса, так вот ваш код с каким-то там


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

Я хотел бы призвать вас хранить ваши высокие баллы в более надежном формате. В частности, я предлагаю 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 будет держать вас от того, чтобы написать свой собственный парсер, чтобы восстановить данные из сохраненных файлов, таких как высокие оценка таблиц. Вы можете просто вставить все в словарь и тривиально вернуть все.

Обратите внимание, что я заправил номер версии, номер версии вашего формата сохранения высоких баллов. Если вы когда-либо измените формат сохранения ваших данных, наличие номера версии там будет очень хорошим.

+0

+1: или yaml, если вы хотите, чтобы он был более понятным для человека (и не нужно отправлять его по проводам) – van

+0

Или вы можете быть традиционным и использовать модуль Python 'pickle'. Это может сохранить любой тип данных Python, и он включен в каждую установку Python. Тем не менее, это не очень понятно для человека. – steveha

0

Что вы хотите, вероятно, то, что обычно известно как «Природная сортировка». Поиск «натурального сорта python» дает много результатов, но есть хорошее обсуждение на ASPN.