【问题标题】:How do I create a dictionary where I add points to names form a text file?如何创建字典,在其中将点添加到文本文件中的名称?
【发布时间】:2015-02-19 17:46:19
【问题描述】:

我正在尝试制作一个评分系统,我得到了一个包含大量(玩家)的文本文件。我已经创建了一个字典并设法在其中添加了所有名称,但是当我尝试添加点时,它们只得到最后一个数字,而不是每个名称的所有组合。那么如何为每个名字新建一个字典,然后加上名字对应的点呢?

所以我基本上需要取其中一个名字“Anders Johansson”并将他的分数添加到他在字典中的名字中,他的名字会以不同的分数多次出现在 score.txt 中。

我的想法是,我不需要运行整个乐谱文件并为每个名字创建一个实例,然后为每个名字添加相应的乐谱,“Anders Johansson”可能会在 score.txt 中出现多达 100 次。 此代码会将名称输入到 final_score 而不是总分。

final_list, file, final_score = [], open('score.txt','r'), {}
string = file.read()
lista = string.split('\n') 
lista.sort()
for i in lista[1:]:
    final_score[str(i[0:-2])] = 0
    final_score[str(i[0:-2])] += int(i[-2:]) # possible error location
final_list = list(final_score.items())
print(sorted(final_list, key=lambda score: score[1],reverse=True))

Example from the file:
Anders Johansson 1
Karin Johansson 1
Eva Johansson 0
Erik Andersson 1
Gunnar Andersson 2
Eva Andersson 1
Nils Eriksson 1
Anders Eriksson 0
Maria Eriksson 1
and so on:

【问题讨论】:

    标签: python dictionary add


    【解决方案1】:

    使用collections.defaultdict

    from collections import defaultdict
    
    final_score = defaultdict(int)
    
    for i in lista[1:]:
        final_score[str(i[0:-2])] += int(i[-2:]) # 
    

    在您的代码中,每次找到 name/key 时,您都会将值 重置0final_score[str(i[0:-2])] = 0,这就是为什么您只实际添加每次最后得分。

    您需要检查密钥是否存在并根据结果进行处理,或者更简单的方法是在您自己的代码中使用dict.setdefault,如果密钥不存在,则创建key/value 配对存在,否则什么都不做:

    for i in lista[1:]:
        final_score.setdefault(str(i[0:-2]), 0)
        final_score[str(i[0:-2])] += int(i[-2:]) # possible error location
    

    你也做了比需要更多的工作,不需要排序,我们可以遍历文件对象并使用rsplit得到namescore

    final_score =  defaultdict(int)
    
    with open('score.txt','r') as f: # with will automatically close your file
        for line in f: # iterate over file object
            # split once on whitespace from right side of string, separating name from score 
            name, score = line.rsplit(None,1)  # unpack 
            # use our defaultdict to increment the score
            final_score[name] += int(score) 
    
    # just call sorted on .items()
    print(sorted(final_score.items(), key=lambda score: score[1], reverse=True))
    

    没有必要进行排序,因为每当我们遇到名称时,我们都会更新 dict 中的值,无论我们遇到名称的顺序是什么,这确实是使用 dict 的优点之一。

    对于final_list.items() 排序,使用operator.itemgetter 也会比使用lambda 更有效:

    from operator import itemgetter
    print(sorted(final_list.items(),key=itemgetter(1),reverse=True))
    

    【讨论】:

    • 谢谢,我对 python 还是很陌生,所以我总是遇到好的和对我来说未知的函数。
    • @FredrikCarlsson,不用担心。 collections 库中有一些非常好的工具值得一试。
    猜你喜欢
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    相关资源
    最近更新 更多