我有这样定义的多行字符串:
foo = """
this is
a multi-line string.
"""
我们用作我正在编写的解析器的测试输入的字符串。解析器功能接收file
-object作为输入并对其进行迭代。它还确实next()
直接调用该方法以跳过行,因此我确实需要一个迭代器作为输入,而不是可迭代的。我需要一个迭代器,它可以在字符串的各个行之间进行迭代,就像file
-object可以在文本文件的行之间进行迭代一样。我当然可以这样:
lineiterator = iter(foo.splitlines())
是否有更直接的方法?在这种情况下,字符串必须遍历一次以进行拆分,然后再由解析器进行遍历。在我的测试用例中,这无关紧要,因为那里的字符串很短,我只是出于好奇而问。Python有很多有用且高效的内置程序,但是我找不到适合这种需求的东西。
这是三种可能性:
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 retval
def f3(foo=foo):
prevnl = -1
while True:
nextnl = foo.find('\n', prevnl + 1)
if nextnl < 0: break
yield foo[prevnl + 1:nextnl]
prevnl = nextnl
if __name__ == '__main__':
for f in f1, f2, f3:
print list(f())
将其运行为主脚本,确认这三个功能等效。使用timeit
(并使用* 100
forfoo
获得大量字符串以进行更精确的测量):
$ 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 StringIO
def 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 StringIO
def f4(foo=foo):
stri = StringIO(foo)
while True:
nl = stri.readline()
if nl == '': break
yield nl.strip('\n')
至少,它不那么冗长。\n
不幸的是,剥离尾部的需要禁止用以下方法更清楚,更快速地替换while
循环return iter(stri)
(iter
在现代版本的Python中,多余的部分是多余的,我相信从2.3或2.4开始,但它也是无害的)。也许值得尝试,也:
return itertools.imap(lambda s: s.strip('\n'), stri)
或其变体-但我在这里停止,因为这几乎是一项strip
基础,最简单,最快的理论性练习。
问题内容: 如何遍历Java中的字符串? 我正在尝试使用foreach样式进行循环 问题答案: 如果要使用增强循环,可以将字符串转换为charArray
问题内容: 我在寻找一个struct的字符串字段遍历,所以我可以做一些清理/验证(与,等)。 现在,我有一个混乱的开关盒,它并没有真正的可扩展性,而且由于这并不是我的应用程序(Web表单)的热点,因此在这里利用杠杆作用似乎是一个不错的选择。 我对于如何实现此功能有点障碍,反射文档对我来说有点困惑(我一直在研究其他一些验证包,但是它们太笨重了,我正在使用大猩猩/模式已用于解组部分): 遍历该结构 对
问题内容: 我想知道如何逐字地遍历一个字符串。 上面给出了输出: 但是我正在寻找以下输出: 问题答案: 当你做- 您不是在遍历字符串中的单词,而是在遍历字符串中的字符。要遍历单词,您首先需要使用将字符串拆分成单词,然后遍历该单词。范例- 请注意,,且不传递任何参数,所有空格都将其分割(空格,多个空格,制表符,换行符等)。
问题内容: 我有一个允许用户上载文本文件或将文件内容复制/粘贴到文本区域的表格。我可以轻松地区分两者,然后将它们输入的任何一个放入字符串变量中,但是我从那里去哪里呢? 我需要遍历字符串的每一行(最好不要担心不同机器上的换行符),确保它只有一个令牌(没有空格,制表符,逗号等),清理数据,然后生成一个SQL查询基于所有方面。 我是一个非常优秀的程序员,所以我知道如何做的一般想法,但是自从使用PHP以来
问题内容: 我想遍历s1以确保s1中的每个字符都包含在s2中。 问题答案: