假设我有一个具有以下结构(名称、分数)的(文本)文件:
a 0
a 1
b 0
c 0
d 3
b 2
等等。我的目标是对每个名字的分数求和,并将它们从最高分到最低分排序。所以在这种情况下,我想要以下输出:
d 3
b 2
a 1
c 0
事先我不知道文件中会有什么名字。
我想知道是否有一种有效的方法来做到这一点。我的文本文件最多可包含 50,000 个条目。
我能想到的唯一方法就是从第 1 行开始,记住该名称,然后遍历整个文件以查找该名称和总和。这看起来非常低效,所以我想知道是否有更好的方法来做到这一点。
最佳答案
将所有数据读入字典:
from collections import defaultdict
from operator import itemgetter
scores = defaultdict(int)
with open('my_file.txt') as fobj:
for line in fobj:
name, score = line.split()
scores[name] += int(score)
和排序:
for name, score in sorted(scores.items(), key=itemgetter(1), reverse=True):
print(name, score)
打印:
d 3
b 2
a 1
c 0
性能
为了检查这个答案与来自@SvenMarnach 的答案的性能,我将这两种方法都放入了一个函数中。这里的 fobj
是一个为读取而打开的文件。
我使用 io.StringIO
所以 IO 延迟应该不会被测量:
from collections import Counter
def counter(fobj):
scores = Counter()
fobj.seek(0)
for line in fobj:
key, score = line.split()
scores.update({key: int(score)})
return scores.most_common()
from collections import defaultdict
from operator import itemgetter
def default(fobj):
scores = defaultdict(int)
fobj.seek(0)
for line in fobj:
name, score = line.split()
scores[name] += int(score)
return sorted(scores.items(), key=itemgetter(1), reverse=True)
collections.Counter
的结果:
%timeit counter(fobj)
10000 loops, best of 3: 59.1 µs per loop
collections.defaultdict
的结果:
%timeit default(fobj)
10000 loops, best of 3: 15.8 µs per loop
看起来 defaultdict
快四倍。我不会猜到这一点。但是当涉及到性能时,您需要进行衡量。
关于python - 高效处理文本文件中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34087263/