如何制作迭代大字符串的字符串式变量?

时间:2013-03-01 17:48:34

标签: python string iterator

在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)

显然存在像这样的。请查看下面的代码,以便有效地将文件流式传输到服务器(from this question)。

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)

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

2 个答案:

答案 0 :(得分: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. 一个调用另一个函数的函数,直到对象的表示形式返回一个空字符串。
  3. 将此示例扩展为打印

    >>> 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异常。

答案 1 :(得分:0)

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

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

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

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