2017-01-01 4 views
5

私は整数を多くの整数が同じ文字列にマップされる単語文字列にマッピングすることを含むPythonユーティリティを構築しています。私の理解では、Pythonは短い文字列とほとんどのハードコーディングされた文字列をデフォルトで使用しています。その結果、文字列の "正規"バージョンをテーブルに保持することによってメモリオーバーヘッドを節約します。文字列のインターンがキーハッシュの最適化のためにより多く構築されているにもかかわらず、文字列値をインターンさせることでこれを恩恵を受けることができると私は考えました。私は長い文字列の文字列の等価性をチェックする簡単なテストを書いた。最初はリストに格納された文字列だけでなく、文字列を値として辞書に格納した。行動は私には予想外である:Pythonでは、別々の辞書文字列値が等価チェックで "in"を渡すのはなぜですか? (文字列インターン実験)

import sys 

top = 10000 

non1 = [] 
non2 = [] 
for i in range(top): 
    s1 = '{:010d}'.format(i) 
    s2 = '{:010d}'.format(i) 
    non1.append(s1) 
    non2.append(s2) 

same = True 
for i in range(top): 
    same = same and (non1[i] is non2[i]) 
print("non: ", same) # prints False 
del non1[:] 
del non2[:] 


with1 = [] 
with2 = [] 
for i in range(top): 
    s1 = sys.intern('{:010d}'.format(i)) 
    s2 = sys.intern('{:010d}'.format(i)) 
    with1.append(s1) 
    with2.append(s2) 

same = True 
for i in range(top): 
    same = same and (with1[i] is with2[i]) 
print("with: ", same) # prints True 

############################### 

non_dict = {} 
non_dict[1] = "this is a long string" 
non_dict[2] = "this is another long string" 
non_dict[3] = "this is a long string" 
non_dict[4] = "this is another long string" 

with_dict = {} 
with_dict[1] = sys.intern("this is a long string") 
with_dict[2] = sys.intern("this is another long string") 
with_dict[3] = sys.intern("this is a long string") 
with_dict[4] = sys.intern("this is another long string") 

print("non: ", non_dict[1] is non_dict[3] and non_dict[2] is non_dict[4]) # prints True ??? 
print("with: ", with_dict[1] is with_dict[3] and with_dict[2] is with_dict[4]) # prints True 

私は非dictのチェックは「偽」のプリントアウトになるだろうと思ったが、私は明らかに間違っていました。誰かが何が起こっているのか、文字列インターンシップが私の場合に何の利益ももたらさないかどうかを知っていますか?複数の入力テキストからデータを統合すると、多くの場合、多くのが単一の値よりも多くのキーを持つことができるので、メモリスペースを節約する方法を探しています。 (多分私はデータベースを使用する必要がありますが、それはこの質問の範囲外です) ありがとうございます!

+1

2357112とは何ですか?構築された文字列は一般的に 'a ="長い文字列 "; b ="長い "+"文字列 "; print(id(a)== id(b))' prints ' False' –

答えて

4

バイトコードコンパイラによって実行される最適化の1つは、インターンと類似していますが、同じコードブロック内の等しい定数に対して同じオブジェクトを使用することです。文字列リテラルは次のとおりです。

は同じコードブロックにあります。したがって、等しい文字列は同じ文字列オブジェクトで表されます。

+0

ああそうだよ!私はこれを試しましたが、実行時のバラツキを導入すると、期待通りの誤ったプリントアウトが発生します。明確化のためにありがとう。 u_in =入力( "ランタイム文字列を入力してください") non_dict = {} non_dict [1] = u_in non_dict + "これは長い文字列である" [2] = + u_in "これは別の長い文字列です" non_dict [3] = "これは長い文字列" + u_in non_dict [4] = "これは別の長い文字列です" + u_in – synchronizer

関連する問題