在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中创建流以从字符串迭代的主要内容,如果未能解决你的问题,请参考以下文章