当前位置:  开发笔记 > 编程语言 > 正文

有效地处理文本文件中的数据

如何解决《有效地处理文本文件中的数据》经验,为你挑选了2个好方法。

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

 a         0
 a         1
 b         0
 c         0
 d         3
 b         2

等等.我的目标是将每个名字的分数相加,并从最高分到最低分.所以在这种情况下,我想要以下输出:

 d         3
 b         2
 a         1
 c         0

事先我不知道文件中会有什么名字.

我想知道是否有一种有效的方法来做到这一点.我的文本文件最多可包含50,000个条目.

我能想到的唯一方法就是从第1行开始,记住该名称,然后查看整个文件以查找该名称和总和.这看起来非常低效,所以我想知道是否有更好的方法来做到这一点.



1> Mike Müller..:

将所有数据读入字典:

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快了四倍.我不会猜到这一点.但是在性能方面你需要衡量.


@IronFist是的,这就是`itemgetter`的作用.这个名字比阅读`lambda`函数更直观.

2> Sven Marnach..:

这是一个很好的用例collections.Counter:

from collections import Counter

scores = Counter()
with open('my_file') as f:
    for line in f:
        key, score = line.split()
        scores.update({key: int(score)})

for key, score in scores.most_common():
    print(key, score)

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有