2

Python で、文字列のように機能する変数を作成できますが、内部では文字列のシーケンスを反復処理しますか?

例えば

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

これは、文字列のリストを反復処理し、効率的に実行します-一度に1つの文字列のみをメモリに保持します。しかし、私が欲しいのは次のようなものです:

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

しかし、これはナイーブなことをしているだけで、セット全体を反復処理し、それらすべてをメモリ内の 1 つの大きな文字列に連結しているだけだと思います。これに関するもう1つの問題は、変数が必要なことです。実際に結合を行うという醜い作業にユーザーをさらす必要はありません。したがって、おそらくユーザーは次のようなことをするでしょう:

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 に答える