词典是否记录了项目分配的时间点?

2024-04-27 01:15:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个高分系统,在这个系统中,用户将输入一个名字和一个分数,然后程序将测试分数是否大于高分中的最低分数。如果是的话,分数会被写出来,最低的分数会被删除。一切正常,但我注意到了一些事情。high_scores.txt文件是这样的:

PL1 50
PL2 50
PL3 50
PL4 50
PL5 50

PL1是第一个添加的分数,PL2是第二个,PL3是第三个,依此类推。然后我试着再加一个分数,比其他所有分数都高(PL6 60),结果是程序将PL1指定为最低分数。PL6已添加,PL1已删除。这正是我想要的行为,但我不明白它是怎么发生的。词典是否记录了项目分配的时间点?代码如下:

MAX_NUM_SCORES = 5

def getHighScores(scores_file):
    """Read scores from a file into a list."""

    try:
        cache_file = open(scores_file, 'r')
    except (IOError, EOFError):
        print("File is empty or does not exist.")
        return []
    else:
        lines = cache_file.readlines()
        high_scores = {}

        for line in lines:
            if len(high_scores) < MAX_NUM_SCORES:
                name, score = line.split()
                high_scores[name] = int(score)
            else:
                break

        return high_scores

def writeScore(file_, name, new_score):
    """Write score to a file."""

    if len(name) > 3:
        name = name[0:3]

    high_scores = getHighScores(file_)

    if high_scores:
        lowest_score = min(high_scores, key=high_scores.get)
        if new_score > high_scores[lowest_score] or len(high_scores) < 5:
            if len(high_scores) == 5:
                del high_scores[lowest_score]

            high_scores[name.upper()] = int(new_score)                  
        else:
            return 0
    else:
        high_scores[name.upper()] = int(new_score)

    write_file = open(file_, 'w')
    while high_scores:
        highest_key = max(high_scores, key=high_scores.get)
        line = highest_key + ' ' + str(high_scores[highest_key]) + '\n'
        write_file.write(line)
        del high_scores[highest_key]

    return 1

def displayScores(file_):
    """Display scores from file."""

    high_scores = getHighScores(file_)

    print("HIGH SCORES")
    if high_scores:
        while high_scores:
            highest_key = max(high_scores, key=high_scores.get)
            print(highest_key, high_scores[highest_key])
            del high_scores[highest_key]
    else:
        print("No scores yet.")

def resetScores(file_):
    open(file_, "w").close()

Tags: keynamereturnifdeflineelse分数
3条回答

不,您得到的结果是由于dict实现内部的任意选择造成的,您不能总是依赖这些选择。(有一个子类dict可以跟踪插入顺序,但是:collections.OrderedDict。)我相信在当前的实现中,如果切换PL1和PL2行的顺序,PL1可能仍然会被删除。你知道吗

正如其他人所指出的,词典中项目的顺序“取决于实现情况”。你知道吗

这个答案更多的是对你的问题的评论,“怎样min()决定什么分数是最低的?”,但对于注释来说太长且格式为y。:-)

有趣的是maxmin都可以这样使用。原因是他们可以研究“iterable”,而字典是iterable:

for i in some_dict:

在字典中的所有键上循环i。在您的例子中,键是用户名。此外,minmax允许传递一个key参数,将iteable中的每个候选变量转换为适合二进制比较的值。因此,min相当于下面的python代码,其中包括一些跟踪,以准确显示其工作原理:

def like_min(iterable, key=None):
    it = iter(iterable)
    result = it.next()
    if key is None:
        min_val = result
    else:
        min_val = key(result)
    print '** initially, result is', result, 'with min_val =', min_val
    for candidate in it:
        if key is None:
            cmp_val = candidate
        else:
            cmp_val = key(candidate)
        print '** new candidate:', candidate, 'with val =', cmp_val
        if cmp_val < min_val:
            print '** taking new candidate'
            result = candidate
    return result

如果我们在示例字典d上运行上述操作,使用d.get作为key

d = {'p': 0, 'ayyy': 3, 'b': 5, 'elephant': -17}
m = like_min(d, key=d.get)
print 'like_min:', m

** initially, result is ayyy with min_val = 3
** new candidate: p with val = 0
** taking new candidate
** new candidate: b with val = 5
** new candidate: elephant with val = -17
** taking new candidate
like_min: elephant

我们发现我们得到了值最小的键。当然,如果多个值相等,“最小”的选择取决于字典迭代顺序(以及min是否实际在内部使用<<=)。你知道吗

(另外,您用来“排序”高分以打印出来的方法是O(n2):选择最高值,从字典中删除,重复直到为空。它遍历n个项目,然后n-1。。。然后是2,然后是1=>;n+(n-1)+…+2+1步=n(n+1)/2=O(n2)。删除高的一个也是一个昂贵的操作,尽管我认为它仍然应该在O或O以下(n2)出现。对于n=5,这不是很糟糕(5*6/2=15),但是。。。不优雅。:-))

这几乎就是http://stromberg.dnsalias.org/~strombrg/python-tree-and-heap-comparison/的意义所在。你知道吗

简短版本:获取treap模块,它的工作方式类似于一个排序字典,并保持键的顺序。或者使用nest模块自动获取n个最大(或最小)值。你知道吗

你知道吗收藏.订购信息有利于保持插入顺序,但不是键顺序。你知道吗

相关问题 更多 >