【问题标题】:Fast/Efficient counting of list of space delimited strings in PythonPython中空格分隔字符串列表的快速/高效计数
【发布时间】:2017-04-26 01:47:18
【问题描述】:

给定输入:

x = ['foo bar', 'bar blah', 'black sheep']

我可以这样做来获取空格分隔字符串列表中每个单词的计数:

from itertools import chain
from collections import Counter
c = Counter(chain(*map(str.split, x)))

或者我可以简单地遍历并得到:

c = Counter()
for sent in x:
    for word in sent.split():
        c[word]+=1

[出]:

Counter({'bar': 2, 'sheep': 1, 'blah': 1, 'foo': 1, 'black': 1})

问题是如果输入的字符串列表非常大,哪个效率更高?还有其他方法可以实现相同的计数器对象吗?

假设它是一个文本文件对象,有数十亿行,每行 10-20 个单词。

【问题讨论】:

  • 假设每个sent 的大小合理,您的第二个解决方案应该尽可能好。当然,您可以手动遍历字符,但我认为这没有任何改进。我对链子不够熟悉,不知道它在这里的表现如何。
  • 你为什么不计时看看?

标签: python dictionary counter itertools chain


【解决方案1】:

假设您使用的是 Python 3x,chain(*map(str.split, x)) 和简单迭代都会从每一行按顺序创建中间列表;这在任何一种情况下都不会占用太多内存。性能应该非常接近,并且可能取决于实现。

然而,创建一个生成器函数来提供 Counter() 是最有效的内存方式。无论您使用 string.split(),它都会创建不必要的中间列表。如果您的线路特别长,这可能会导致速度变慢,但老实说这不太可能。

这样的生成器函数如下所述。请注意,为了清楚起见,我使用了可选类型。

from typing import Iterable, Generator
def gen_words(strings: Iterable[str]) -> Generator[str]:
    for string in strings:
        start = 0
        for i, char in enumerate(string):
            if char == ' ':
                if start != i:
                    yield string[start:i]
                start = i
        if start != i:
            yield string[start:i]
c = counter(gen_words(strings))

【讨论】:

    【解决方案2】:

    您的问题的答案是profiling

    以下是一些分析工具:

    【讨论】:

      猜你喜欢
      • 2021-07-13
      • 1970-01-01
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多