python - 高效处理文本文件中的数据

标签 python file

假设我有一个具有以下结构(名称、分数)的(文本)文件:

 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/

相关文章:

java.io.IOException : The system cannot find the path specified 异常

c - 在 C 中的 I/O 期间打印的交替行

java - 如何设置文件输入流的路径

python - 在 python 中迭代大型 CSV 文件时如何轻松内存?

python - 保存边框图像

python - 将十六进制数字相加而不转换基数?

python - 查找所有div,从span中抓取

python - Python Selenium-尝试除外的无效语法错误

java - 从文件读取字节或向文件写入字节

Android 文件选择器将音频文件重定向到/外部