【问题标题】:Fastest way to create a list of overlapping substrings from a string in Python从 Python 中的字符串创建重叠子字符串列表的最快方法
【发布时间】:2013-01-11 10:30:32
【问题描述】:

我正在尝试生成给定字符串中所有重叠的 n 长度子字符串的列表。

例如,对于6 和字符串"hereismystring",我将生成列表["hereis", "ereism", "reismy", ..., "string"]。我现在使用的简单代码如下所示:

n = 6
l = len(string)
substrings = [string[i:(i + n)] for i in xrange(l - n + 1)]

很简单。问题是,我想加快速度(我有很多很长的字符串)。 Python中有更快的技术吗?考虑到 Python 的字符串例程无论如何都在 C 中,是否会下降到 Cython 帮助?

作为参考,对于 500 长度的字符串和 30 的 n,此技术在我的机器(新的 Macbook Pro)上大约需要 100us。

提前感谢您的帮助!

【问题讨论】:

  • Cython 肯定会为您提供更快的速度,但您真的需要这种优化吗?
  • FWIW,在我的旧 macbook 上,使用 pypy 而不是 CPython 将时间从 ~150 us 减少到 ~32 us,至少在它预热之后。如果您只需要几个因素,可能值得一试。
  • 一旦生成这些子字符串,您打算做什么?这可以为决定提供依据。

标签: python string performance cython


【解决方案1】:

从哪种 Python 编码技术最快的问题上退后一步,我会以不同的方式处理这个问题。由于所有字符串的长度相同,并且都来自单个源字符串,为什么不直接使用字符范围,而不是将它们转换为正确的字符串呢?您将避免大量分配和复制,但您必须调整代码以知道每个“字符串”的长度为 n 个字符。

换句话说,当您想使用子字符串时,只需直接从源字符串中读取范围。您将尽可能快地从缓存中提取所需的字符。您可以将“子字符串”仅表示为源字符串的偏移量。

有时,如果您想要超快的性能,您必须放弃熟悉的数据结构。只是一个想法。

【讨论】:

    【解决方案2】:

    怎么样:

    >>> d = deque("hereismystring")
    >>> s = ''.join(d)[:6]
    >>> while not len(s) % 6:
    ...    print s
    ...    _ = d.popleft()
    ...    s = ''.join(d)[:6]
    ... 
    hereis
    ereism
    reismy
    eismys
    ismyst
    smystr
    mystri
    ystrin
    string
    >>> 
    

    我相信双端队列是 O(1) 而列表是 O(n)

    【讨论】:

    • 这比 OPs 解决方案慢。 deque 生成实际上是O(nlon n) 操作,而且检索元素具有复杂性O(logn),因此检索所有元素将具有复杂性O(nlogn)。另一个操作是 join,它对每个 n - 6 切片运行 n 次。因此join 操作具有复杂度顺序O(n^2)。总结一下,对于整个操作,复杂度的顺序是O(n^2)。在测试运行中,双端队列的实现速度几乎慢了 7 倍。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多