2017-02-01 27 views
2

私はコードをより効率的に(効率的に)作りたいと思っています。今、私たちは次のようにパラメータとしてのiterableを取る機能がたくさんあります。Pythonの空のタプルは「定数」

def foo(para,meter,iterable): 
    #... 
    pass 

をし、時には我々はそれを適切に仕事をするために、空のリストを提供する必要がありますfoo(14,25,[])。問題は、新しいリストが作成されるたびに、ヒープに割り当てる必要があり、空のタプルだけ が(潜在的に1つの)タプルを取るのに対し、リストは64バイトのメモリ(自分のマシンではsys.getsizeof([])でテスト)時間)48バイト。

したがって、私は空のタプルが定数かどうか疑問に思っていました。タプルは不変なので、プログラム内では長さ0(だから())のタプルを簡単に作ることができます。これにより、「構築時間」が短縮されます(定数への参照を設定するだけなので、まったく存在しません)。

私の質問は、空のタプルが実際には()が建設時間を必要とせず、追加のメモリを割り当てるような定数であるというPythonインタプリタ(一般的なインタプリタ)に関する保証があるかどうかです。

>>> id(()) 
140290183798856 
>>> a =() 
>>> id(a) 
140290183798856 

が、それは実行時にPythonインタプリタフォーク何らかの理由タプルいる可能性が考えられます。

id(..)とのテストそれはそこだけで1つのゼロ組が実際にあるという理論をサポートするように思われます。

+0

http://stackoverflow.com/q/38328857/2301450 – vaultah

+0

@vaultah:質問はなぜではありませんでした。私は、カーテンの後ろでどのように動作するのかというアイデアがあることは明らかです。問題は**常に**が()が()であるかどうかです。 –

+0

私はジムの答えもそれをカバーすると思いますか? – vaultah

答えて

8

CPythonでは、空のタプルはシングルトンです。 1つのコピーのみが作成され、その後、()を使用するたびに再利用されるか、または空のジェネレータでtuple()を使用します。

if (size == 0 && free_list[0]) { 
    op = free_list[0]; 
    Py_INCREF(op); 
    // ... 
    return (PyObject *) op; 
} 

タプルサイズが0(空)とfree_list[0]オブジェクトが(既存の空のタプルシングルトン)の存在であり、もしそうであれば、単にそれを使用:

PyTuple_new() functionは、本質的に、これはありません。

free_listの詳細については、How is tuple implemented in CPython?を参照してください。また、CPythonは既に作成されたtupleのインスタンスを長さ20まで再利用します。

これはのです。他の実装(Jython、IronPython、PyPy)でも同じことをする必要はありません。

関連する問題