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

Posted

技术标签:

【中文标题】在Python中创建流以从字符串迭代【英文标题】:creating stream to iterate over from string in Python 【发布时间】:2014-03-17 14:40:42 【问题描述】:

我想从 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

【问题讨论】:

【参考方案1】:

我想从 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() # where we are in the object now
0

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

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

>>> m_2 = file_like_io.readlines() 

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

>>> m_1 == m_2
True

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

【讨论】:

【参考方案2】:

您可以像这样使用简单的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 可能更快(我还没有测试过),但这会给你定义/使用分隔符的灵活性。

【讨论】:

以上是关于在Python中创建流以从字符串迭代的主要内容,如果未能解决你的问题,请参考以下文章

如何从具有小数类型列的主题在 ksql 中创建流

java.io.StringBufferInputStream

转换流以将字符串添加到每一行

Java字符流和字节流对文件操作的区别

在 Python 中迭代字符串索引时遇到问题

在 python 中创建字符串数组的最佳方法是啥?