创建流以在Python中从字符串迭代

时间:2014-02-18 03:22:20

标签: python string io

我想从Python中的字符串创建一个流,这样就相当于读取字符串,就像从文本文件中读取一样。类似的东西:

for line in open('myfile.txt'): print line

除了'myfile.txt'的内容存储在字符串s中。这是正确/最好的方法吗?

s = StringIO.StringIO("a\t\b\nc\td\n")
for line in s: print line

2 个答案:

答案 0 :(得分:4)

  

我想从Python中的字符串创建一个流,这样就相当于读取字符串,就像从文本文件中读取一样。

     

这是正确/最好的方法吗?

是的,除非你确实想要它在列表中。

如果打算逐行消费,那么你的做法是有意义的。

StringIO()创建一个类似文件的对象。

文件对象有一个方法.readlines(),它将对象实现为列表。您可以迭代它,而不是实现列表中的数据,这是更多的内存光:

# from StringIO import StringIO # Python 2 import
from io import StringIO # Python 3 import

txt = "foo\nbar\nbaz"

这里我们将每行附加到列表中,以便我们可以演示迭代文件类对象并保持数据句柄。 (效率更高的是list(file_like_io)

m_1 = []
file_like_io = StringIO(txt)
for line in file_like_io:
    m_1.append(line)

现在:

>>> m_1
['foo\n', 'bar\n', 'baz']

您可以使用seek

将io返回到任何索引点
>>> file_like_io.seek(0)
>>> file_like_io.tell() #print where we are in the object now
0

如果你真的想要它在列表中

.readlines()实现StringIO迭代器,就好像list(io)一样 - 这被认为不太可取。

>>> m_2 = file_like_io.readlines() 

我们可以看到我们的结果是一样的:

>>> m_1==m_2
True

请记住,它是在换行符之后拆分,同时在文本中保留它们,因此每个打印行都会有两个换行符,打印时会有双倍行距。

答案 1 :(得分:0)

您可以使用这样的简单generator function滚动自己:

def string_stream(s, separators="\n"):
    start = 0
    for end in range(len(s)):
        if s[end] in separators:
            yield s[start:end]
            start = end + 1
    if start < end:
        yield s[start:end+1]

使用示例:

>>> stream = string_stream("foo\tbar\nbaz\n", "\t\n")
>>> for s in stream:
...     print(s)
...
foo
bar
baz

cStringIO可能更快(我还没有测试过),但这可以让您灵活地定义/使用分隔符。