遍历字符串的行

遍历字符串的行,第1张

遍历字符串的行

这是三种可能性:

foo = """this is a multi-line string."""def f1(foo=foo): return iter(foo.splitlines())def f2(foo=foo):    retval = ''    for char in foo:        retval += char if not char == 'n' else ''        if char == 'n': yield retval retval = ''    if retval:        yield retvaldef f3(foo=foo):    prevnl = -1    while True:      nextnl = foo.find('n', prevnl + 1)      if nextnl < 0: break      yield foo[prevnl + 1:nextnl]      prevnl = nextnlif __name__ == '__main__':  for f in f1, f2, f3:    print list(f())

将其运行为主脚本,确认这三个功能等效。使用

timeit
(并使用
* 100
for
foo
获得大量字符串以进行更精确的测量):

$ python -mtimeit -s'import asp' 'list(asp.f3())'1000 loops, best of 3: 370 usec per loop$ python -mtimeit -s'import asp' 'list(asp.f2())'1000 loops, best of 3: 1.36 msec per loop$ python -mtimeit -s'import asp' 'list(asp.f1())'10000 loops, best of 3: 61.5 usec per loop

注意,我们需要

list()
调用以确保遍历迭代器,而不仅仅是构建迭代器。

IOW,天真的实现要快得多,甚至都不有趣:比我尝试

find
调用快6倍,而调用比底层方法快4倍。

经验教训:测量永远是一件好事(但必须准确);像这样的字符串方法

splitlines
以非常快的方式实现;通过在非常低的级别上进行编程(尤其是通过
+=
非常小的片段的循环)来将字符串组合在一起可能会非常缓慢。

编辑 :添加了@Jacob的建议,对其进行了稍加修改以使其与其他建议相同(保留行尾空白),即:

from cStringIO import StringIOdef f4(foo=foo):    stri = StringIO(foo)    while True:        nl = stri.readline()        if nl != '': yield nl.strip('n')        else: raise StopIteration

测量得出:

$ python -mtimeit -s'import asp' 'list(asp.f4())'1000 loops, best of 3: 406 usec per loop

不如

.find
基于基础的方法好-
仍然要牢记,因为它可能不大可能出现小的一次性错误(如
f3
上面所述,任何出现+1和-1的循环都应该自动触发一个个的怀疑-
许多缺乏这种调整的循环也应该具有它们-尽管我相信我的代码也是正确的,因为我能够用其他功能检查其输出。’‘

但是基于拆分的方法仍然占主导地位。

顺便说一句:可能更好的样式

f4
是:

from cStringIO import StringIOdef f4(foo=foo):    stri = StringIO(foo)    while True:        nl = stri.readline()        if nl == '': break        yield nl.strip('n')

至少,它不那么冗长。

n
不幸的是,剥离尾部的需要禁止用以下方法更清楚,更快速地替换
while
循环
returniter(stri)
iter
在现代版本的Python中,多余的部分是多余的,我相信从2.3或2.4开始,但它也是无害的)。也许值得尝试,也:

    return itertools.imap(lambda s: s.strip('n'), stri)

或其变体-但我在这里停止,因为这几乎是一项

strip
基础,最简单,最快的理论性练习。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5643749.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存