回答:
速度に関しては、空のリスト/辞書の競合ではありません。
>>> from timeit import timeit
>>> timeit("[]")
0.040084982867934334
>>> timeit("list()")
0.17704233359267718
>>> timeit("{}")
0.033620194745424214
>>> timeit("dict()")
0.1821558326547077
空でない場合:
>>> timeit("[1,2,3]")
0.24316302770330367
>>> timeit("list((1,2,3))")
0.44744206316727286
>>> timeit("list(foo)", setup="foo=(1,2,3)")
0.446036018543964
>>> timeit("{'a':1, 'b':2, 'c':3}")
0.20868602015059423
>>> timeit("dict(a=1, b=2, c=3)")
0.47635635255323905
>>> timeit("dict(bar)", setup="bar=[('a', 1), ('b', 2), ('c', 3)]")
0.9028228448029267
また、ブラケット表記を使用すると、リストと辞書の内包表記を使用できるため、十分な理由になる場合があります。
timeit()
関数は指定された回数の反復を実行するための合計時間を報告1000000
します。これはデフォルトです。したがって、上記の例は、コードスニペットを100万回実行するための秒数です。たとえば、timeit('dict()', number=1) // -> 4.0531158447265625e-06
(1回の反復)while timeit('dict()') // -> 0.12412905693054199
(100万回の反復)
私の意見[]
で{}
は、空のリスト/辞書を作成するための最もpythonicで読みやすい方法です。
set()
たとえば、に注意してください。
this_set = {5}
some_other_set = {}
混乱する可能性があります。1つ目は1つの要素を持つセットを作成し、2つ目はセットではなく空の辞書を作成します。
{}
常に空の辞書を作成します。{1,2,3}
は2.7以降でセットを作成しますが2.6
、以前のバージョンでは構文エラーです。
some_epic_set
は、空のdict
オブジェクトを指す名前の変数です...空のセットではありません。空のセットの場合は、を使用する必要がありますset()
。
{5}
一つの要素とのセットを作成し、5
そして{}
空の辞書です。
辞書のリテラルがあるかもしれない小さなそのバイトコードが短いほど少し速く:
In [1]: import dis
In [2]: a = lambda: {}
In [3]: b = lambda: dict()
In [4]: dis.dis(a)
1 0 BUILD_MAP 0
3 RETURN_VALUE
In [5]: dis.dis(b)
1 0 LOAD_GLOBAL 0 (dict)
3 CALL_FUNCTION 0
6 RETURN_VALUE
同じことがlist
vsにも適用されます[]
CALL_FUNCTION
かかる少なくともとして多くの時間として、BUILD_MAP
(基本的に呼び出される関数であるBUILD_MAP
)、およびLOAD_GLOBAL
取るだけで余分なオーバーヘッドです。
[]とlist()の違いについては、他の誰も指摘していない落とし穴があります。リストのメンバーとして辞書を使用する場合、2つはまったく異なる結果になります。
In [1]: foo_dict = {"1":"foo", "2":"bar"}
In [2]: [foo_dict]
Out [2]: [{'1': 'foo', '2': 'bar'}]
In [3]: list(foo_dict)
Out [3]: ['1', '2']
[foo_dict]
を使用した場合と同じ結果が得られlist((foo_dict,))
ます。このlist()
メソッドは、唯一のパラメーターとして反復可能オブジェクトを取り、それを反復処理して要素をリストに追加します。これはlist(some_list)
、リストを平坦化することにより、同様の落とし穴を引き起こします。
list()と[]の動作は異なります。
>>> def a(p=None):
... print(id(p))
...
>>> for r in range(3):
... a([])
...
139969725291904
139969725291904
139969725291904
>>> for r in range(3):
... a(list())
...
139969725367296
139969725367552
139969725367616
list()は常にヒープ内に新しいオブジェクトを作成しますが、[]は多くの理由でメモリセルを再利用できます。
以下の例に示すように、[]とlist()の動作には1つの違いがあります。数値のリストを返す場合はlist()を使用する必要があります。それ以外の場合は、マップオブジェクトを取得します。それを説明する方法がわかりません。
sth = [(1,2), (3,4),(5,6)]
sth2 = map(lambda x: x[1], sth)
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
sth2 = [map(lambda x: x[1], sth)]
print(sth2) # print returns object <map object at 0x000001AB34C1D9B0>
type(sth2) # list
type(sth2[0]) # map
sth2 = list(map(lambda x: x[1], sth))
print(sth2) #[2, 4, 6]
type(sth2) # list
type(sth2[0]) # int
ボックスブラケットのペアは、リストオブジェクト、またはインデックスの添え字my_List [x]のいずれかを示します。
中括弧のペアは、辞書オブジェクトを示します。
a_list = ['on'、 'off'、1、2]
a_dict = {オン:1、オフ:2}
ほとんどの場合、それは主に選択の問題です。それは好みの問題です。
ただし、たとえば数値キーがある場合は実行できないことに注意してください。
mydict = dict(1="foo", 2="bar")
あなたはしなければならない:
mydict = {"1":"foo", "2":"bar"}
mydict = {1:"foo", 2:"bar"}
(キーの引用符なしで)行う必要があります。
list(i for i in range(10) if i % 2)