[]と{} vs list()とdict()のどちらが良いですか?


113

どちらも基本的には同じものですが、スタイルの点では、空のリストまたは辞書を作成するために使用する方が(よりPythonicの方が)優れていることを理解しています。

回答:


197

速度に関しては、空のリスト/辞書の競合ではありません。

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

また、ブラケット表記を使用すると、リストと辞書の内包表記を使用できるため、十分な理由になる場合があります。


4
口述およびリストの理解は、英語の名前を使用して行うこともできます。例:list(i for i in range(10) if i % 2)
Zags

4
{}と[]が非常に高速である理由はありますか?単なるエイリアスだと思っていました。
ジャスティンD.

時間は正確な時間を与えていないようです。ベンチマークによると、通常のhttp呼び出しよりもかなり遅い200ミリ秒かかるようです。通常はシェルでdict()を実行してから、timeit( "dict()")を実行してみてください。実行時に目に見える違いがわかります。
piyush

2
@piyush実際には、timeit()関数は指定された回数の反復を実行するための合計時間を報告1000000します。これはデフォルトです。したがって、上記の例は、コードスニペットを100万回実行するための秒数です。たとえば、timeit('dict()', number=1) // -> 4.0531158447265625e-06(1回の反復)while timeit('dict()') // -> 0.12412905693054199(100万回の反復)
Greg Haskins

@GregHaskinsなので、その場合、100万のレコードをループしてループでdict()を使用しない限り、dict()や{}の使用について心配する必要はないと思います。
piyush

37

私の意見[]{}は、空のリスト/辞書を作成するための最もpythonicで読みやすい方法です。

set()たとえば、に注意してください。

this_set = {5}
some_other_set = {}

混乱する可能性があります。1つ目は1つの要素を持つセットを作成し、2つ目はセットではなく空の辞書を作成します。


4
{}常に空の辞書を作成します。{1,2,3}は2.7以降でセットを作成しますが2.6、以前のバージョンでは構文エラーです。
ThiefMaster 2011

1
ごめんなさい?これsome_epic_setは、空のdictオブジェクトを指す名前の変数です...空のセットではありません。空のセットの場合は、を使用する必要がありますset()
6502

2
6502 @:確かに、それは一般的な落とし穴ある{5}一つの要素とのセットを作成し、5そして{}空の辞書です。
orlp 2011

1
うわー、それは混乱していた。それでも、フラクタルオブバッドデザインレベルの混乱ではありません。:-)
ファルケン教授、2012

4
@EnderLook:実際には、一般化された展開では、リテラル構文を使用{*()}して空にすることができsetます。私はそれを片目猿オペレーターと呼んでいます。:-)
ShadowRanger 2018年

17

辞書のリテラルがあるかもしれない小さなそのバイトコードが短いほど少し速く:

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

同じことがlistvsにも適用されます[]


8
これは、BUILD_MAPおよびLOAD_GLOBALが一定の時間であり、同じ時間がかかることを前提としています。ありそうもない。timeitははるかに優れた推定を提供します。
Jamie Pate 2014年

それどころか、CALL_FUNCTIONかかる少なくともとして多くの時間として、BUILD_MAP(基本的に呼び出される関数であるBUILD_MAP)、およびLOAD_GLOBAL取るだけで余分なオーバーヘッドです。
chepner


3

[]と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)、リストを平坦化することにより、同様の落とし穴を引き起こします。
sotrh 2018年

1

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()は常にヒープ内に新しいオブジェクトを作成しますが、[]は多くの理由でメモリセルを再利用できます。


0

以下の例に示すように、[]と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

range()関数の例を使用して動作を説明しているようです>>> print(range(10))#range(0、10)range()はリストのように動作しますが、リストではありません。それはあなたがそれを反復するときにシーケンスからの連続したアイテムを返すオブジェクトです、それは実際にはリストを作成せず、スペースを節約します。このようなオブジェクトは反復可能です。つまり、供給がなくなるまで連続したアイテムを取得できるものを期待する関数や構造のターゲットとして適しています。関数list()は、反復可能オブジェクトからリストを作成します。>>> list(range(5))#[0、1、2、3、4]
sebtac '22年

1
その結果、[]は反復可能なオブジェクトを格納します。list()は同じ
イテラブル

0

ボックスブラケットのペアは、リストオブジェクト、またはインデックスの添え字my_List [x]のいずれかを示します。

中括弧のペアは、辞書オブジェクトを示します。

a_list = ['on'、 'off'、1、2]

a_dict = {オン:1、オフ:2}


-5

ほとんどの場合、それは主に選択の問題です。それは好みの問題です。

ただし、たとえば数値キーがある場合は実行できないことに注意してください。

mydict = dict(1="foo", 2="bar")

あなたはしなければならない:

mydict = {"1":"foo", "2":"bar"}

7
これは間違っています... mydict = {1:"foo", 2:"bar"}(キーの引用符なしで)行う必要があります。
6502 2011

8
それは単に「間違った」ものではありません。キーは、引用符で囲むかどうかに応じて、文字列/整数になります。
ThiefMaster 2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.