插入根据python中的属性排序的文件(.txt)对象

时间:2016-12-06 12:15:36

标签: python file sorting

我想在根据属性排序的文件(.txt)中插入对象(在这种情况下得分是属性)

class list():

    def __init__(self, name, score):

        self.name = name
        self.score = score

    def insert(self):

        outfile = open('list.txt', 'a') 
        outfile.write(self.name + ':' + self.score + '\n')
        outfile.close()

我该怎么做,首先检查文件以查看文件中的所有对象,然后以最佳顺序插入对象。

(我们希望对游戏进行排名,每次用户玩游戏时,我们都希望插入用户并按分数排序分数)

2 个答案:

答案 0 :(得分:0)

插入写入位置非常难以插入文本文件。然而,阅读内容,对其进行排序并再次将其写回来很容易 要正确排序,您需要先读取数据:

with open('list.txt', 'r') as file_:
    string_list = file_.readlines()

您将其读入name : score列表格式:

sorted_list = [line.split(':') for line in string_list]

您插入元素:

sorted_list.append([name, score])

并为第二个元素排序:

sorted_list.sort(key = lambda (name, score): score)

现在您可以将其写回文件

with open('list.txt', 'w') as outfile:
    outfile.writelines(['{0} : {1}'.format(name, score) for 
                        (name, score) in sorted_list])

这可以做你想做的事。现在你只需要以类的形式重写它。 到目前为止,您对字符串执行排序,您也可以先将字符串转换为您的类型。

可能的课程:

class my_list():

    def __init__(self, name, score):

        self.name = name
        self.score = score
        self.existing = None

    def read_list(self):
        with open('list.txt', 'r') as file_:
            string_list = file_.readlines()
        self.existing = [line.split(':') for line in string_list]

    def insert(self):
        if self.existing is None:
           self.existing = []
        self.existing.append([self.name, self.score])
        self.existing.sort(key = lambda (name, score): score)
        with open('list.txt', 'w') as outfile:
            outfile.writelines(['{0} : {1}\n'.format(name, score) for 
                                (name, score) in self.existing])

可能更好的设计课程:

class my_list():
    def __init__(self, filename, score_type=int):
        self.filename = filename
        self.score_type = score_type
        self.existing = None
        self.read_list()

    def read_list(self):
        with open(self.filename, 'r') as listfile:
            string_list = listfile.readlines()
        raw_list = [line.split(':') for line in string_list]
        self.existing = [[name.strip(), self.score_type(score.strip())] 
                         for name, score in raw_list]

    def insert(self, name, score):
        self.existing.append([name, score])

    def sort(self):
        self.existing.sort(key = lambda (name, score): score)

    def write_sorted(self):
        self.sort()
        with open(self.filename, 'w') as outfile:
            outfile.writelines(['{0} : {1}\n'.format(name, score) for
                                (name, score) in self.existing])

#testing it:
test = my_list('list.txt')
test.read_list()
test.insert('horst', 7)
test.write_sorted()

编辑:
- 固定命名问题
- 修改后的第二个类,将score存储为int

答案 1 :(得分:0)

我建议您将分数数据保存在内存中,而不是一遍又一遍地写入文件。只要在严格必要时写入文件,就认为从/向内存读/写比磁盘访问快。以下是一个简单基本用法的基本示例:

import json
import pprint
import random


class Score():

    def __init__(self):
        self.data = []

    def load(self, filename='score.txt'):
        with open(filename, 'r') as f:
            self.data = json.load(f)

    def save(self, filename='score.txt'):
        with open(filename, 'w') as f:
            json.dump(self.data, f)

    def insert(self, name, score):
        self.data.append((name, score))
        self.data.sort(key=lambda x: x[1], reverse=True)

    def __repr__(self):
        return pprint.pformat(self.data, indent=4)

if __name__ == "__main__":
    s = Score()

    names = ["Peter", "Jhon", "Lewis", "Sam"]
    for i in range(10):
        s.insert(random.choice(names), random.randint(0, 1000))

    print(s)
    s.save("score1.txt")
    print('-' * 80)

    for i in range(10):
        s.insert(random.choice(names), random.randint(0, 1000))

    print(s)
    s.save("score2.txt")
    print('-' * 80)

    s.load("score1.txt")
    print(s)

请记住上面的例子可以改进很多,如果你的最终得分数据结构不会很大,这种方法会很好。否则,您可以考虑使用bisect模块,这样您就可以保留已经排序的结构,这样您就不需要反复排序。如果事情开始变得比简单游戏更复杂,那么你可能需要开始考虑另一种更有效的数据结构,比如数据库。无论如何,KISS