2

在 Python 中,我可以构建一个类似于字符串但在内部迭代字符串序列的变量吗?

例如

def function_a():
    for i in xrange(100000000):
        yield str(i)

这将遍历一个字符串列表并且它会有效地完成它 - 一次只在内存中保留一个字符串。但我想要的是这样的:

''.join([s for s in function_a()])

但我敢打赌,这只是做天真的事情,遍历整个集合并将它们全部连接到内存中的一个大字符串中。另一个问题是我想要一个变量,我不想让用户接触到实际进行连接的丑陋工作。所以也许用户会做类似的事情:

magic_str = get_long_but_memory_efficient_str()

然后使用它有效地打印到屏幕上(并随时释放内存):

print magic_str

或者我对它的真正用途是将 HTTP 流式传输到服务器:

request = urllib2.Request(url, magic_str)

显然存在这样的事情。查看下面的代码以有效地将文件流式传输到服务器(来自这个问题)。

f = open('somelargefile.zip','rb')
mmapped_file_as_string = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
request = urllib2.Request(url, mmapped_file_as_string)
request.add_header("Content-Type", "application/zip")
response = urllib2.urlopen(request)

但是我的情况不同,因为我正在构建要流式传输到服务器的字符串。

4

2 回答 2

2

根据您的实际需要更新答案

>>> class MagicString(str):
    def __init__(self, gen):
        self.gen = gen
    def __str__(self):
        try:
            return self.gen.next()
        except StopIteration:
            return '' #boolean value = False


>>> def run_efficiently(some_function, magic_str):
    substr = str(magic_str)
    while substr:
        some_function(substr)
        substr = str(magic_str)

说明:您需要以下组合:

  1. 使用生成器产生子字符串的对象(例如在字符串表示上)
  2. 一个函数调用另一个函数,直到对象的表示返回一个空字符串。

将此示例扩展到 print

>>> import sys
>>> def print_without_breaks(some_string):
    sys.stdout.write(some_string)

>>> s = MagicString(c for c in '12345')
>>> run_efficiently(print_without_breaks, s)
12345

您可以根据实际需要使用类似的方法,您可以对每个请求的返回值做一些有用的事情。

所以也许,你根本不需要变量/对象......只是一些重复运行的简单代码,直到你的生成器吐出一个StopIteration异常。

于 2013-03-01T18:24:55.253 回答
0

不确定我完全理解你想要什么,但在我看来,你担心 python 字符串的不变性。

join 不会像您想象的那样创建很多临时对象。如果您已经有一个列表, ''.join 将非常有效,并且只会创建一个字符串。

如果您没有理由使用要连接的对象创建列表,只需使用 cStringIO 模块。这将使用最少的内存。

如果您仍然担心,或者您是顽固的 C 程序员,不理解人们如何看不到空终止的字节序列是上帝希望我们处理字符串的方式,那么用 C 编写您的那部分代码,这是例如,与 Java 相比,这在 python 中非常有用。

于 2013-03-01T18:12:54.723 回答