web-dev-qa-db-ja.com

dictリテラルとdictコンストラクターの使用に違いはありますか?

PyCharmを使用して、dict literalを変換することを提案しています

d = {
    'one': '1',
    'two': '2',
}

dictコンストラクター

d = dict(one='1', two='2')

これらの異なるアプローチはいくつかの重要な点で異なりますか?

(この質問を書いている間、dict()を使用すると数値キーを指定することは不可能に思えます。_d = {1: 'one', 2: 'two'}は可能ですが、明らかにdict(1='one' ...)は不可能です。

182
maligree

最も明らかな違いを指摘されたと思います。それとは別に、

最初のものはdictを検索する必要がないため、少し速くなります

2番目はlocals()dictを検索してからglobals()を検索し、組み込み関数を見つけるため、たとえばdictと呼ばれるローカルを定義することで動作を切り替えることができます。

107
John La Rooy

リテラルは、汎用CALL_FUNCTIONではなく最適化されたBUILD_MAPおよびSTORE_MAPオペコードを使用するため、はるかに高速です。

> python2.7 -m timeit "d = dict(a=1, b=2, c=3, d=4, e=5)"
1000000 loops, best of 3: 0.958 usec per loop

> python2.7 -m timeit "d = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}"
1000000 loops, best of 3: 0.479 usec per loop

> python3.2 -m timeit "d = dict(a=1, b=2, c=3, d=4, e=5)"
1000000 loops, best of 3: 0.975 usec per loop

> python3.2 -m timeit "d = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5}"
1000000 loops, best of 3: 0.409 usec per loop
49
Daniel Kluev

Python 3.2でもほとんど同じように見えます。

Gnibblerが指摘したように、最初のものはdictをルックアップする必要がありません。

>>> def literal():
...   d = {'one': 1, 'two': 2}
...
>>> def constructor():
...   d = dict(one='1', two='2')
...
>>> import dis
>>> dis.dis(literal)
  2           0 BUILD_MAP                2
              3 LOAD_CONST               1 (1)
              6 LOAD_CONST               2 ('one')
              9 STORE_MAP
             10 LOAD_CONST               3 (2)
             13 LOAD_CONST               4 ('two')
             16 STORE_MAP
             17 STORE_FAST               0 (d)
             20 LOAD_CONST               0 (None)
             23 RETURN_VALUE
>>> dis.dis(constructor)
  2           0 LOAD_GLOBAL              0 (dict)
              3 LOAD_CONST               1 ('one')
              6 LOAD_CONST               2 ('1')
              9 LOAD_CONST               3 ('two')
             12 LOAD_CONST               4 ('2')
             15 CALL_FUNCTION          512
             18 STORE_FAST               0 (d)
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE
38
Paolo Moretti

これらの2つのアプローチは、Pythonの字句規則が干渉する場合を除いて、同じ辞書を生成します。

辞書リテラルはもう少し明らかに辞書であり、任意の種類のキーを作成できますが、キー名を引用符で囲む必要があります。一方、何らかの理由で必要な場合は、キーに変数を使用できます。

a = "hello"
d = {
    a: 'hi'
    }

dict()コンストラクターは、入力の形式がさまざまであるため、柔軟性が向上します。たとえば、ペアのイテレータを提供することができ、キー/値のペアとしてそれらを扱います。

PyCharmが1つのフォームを他のフォームに変換する理由を私は知りません。

13
Ned Batchelder

python 3.4 + pycharmとの大きな違いは、キーの数が256を超えると、dict()コンストラクターが「構文エラー」メッセージを生成することです。

今はdictリテラルを使用することを好みます。

7
Michel

python 2.7チュートリアルから:

中括弧のペアは、空の辞書{}を作成します。中括弧内にkey:valueペアのコンマ区切りリストを配置すると、初期のkey:valueペアが辞書に追加されます。これは、辞書が出力に書き込まれる方法でもあります。

tel = {'jack': 4098, 'sape': 4139}
data = {k:v for k,v in Zip(xrange(10), xrange(10,20))}

一方:

Dict()コンストラクターは、タプルとして保存されたキーと値のペアのリストから直接辞書を作成します。ペアがパターンを形成するとき、リスト内包表記はキーと値のリストをコンパクトに指定できます。

tel = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)]) {'sape': 4139, 'jack': 4098, 'guido': 4127}
data = dict((k,v) for k,v in Zip(xrange(10), xrange(10,20)))

キーが単純な文字列の場合、キーワード引数を使用してペアを指定する方が簡単な場合があります。

dict(sape=4139, guido=4127, jack=4098)
>>>  {'sape': 4139, 'jack':4098, 'guido': 4127}

したがって、{}とdict()は両方とも辞書を作成しますが、辞書データの初期化の方法は少し異なります。

6

Dict継承クラス、追加メソッドを持つカスタムdictクラスを作成するdictリテラルはありません。このような場合、カスタムdictクラスコンストラクターを使用する必要があります。次に例を示します。

class NestedDict(dict):

    # ... skipped

state_type_map = NestedDict(**{
    'owns': 'Another',
    'uses': 'Another',
})
2
Dmitriy Sintsov

Dictリテラルd = {'one': '1'}は、物事の値を割り当ててdict()コンストラクターに送信するのではなく、はるかに読みやすい定義データであることがわかりました。

その一方で、現代ではpython 2.7+がセットを作成するd = {'one', '1'}としてdictリテラルを誤って入力するのを見てきました。

それにもかかわらず、私はそれがより読みやすく、個人的な好みだと思うので、私はまだセットリテラルを使用することを好みます。

1
lee penkman

dict()リテラルは、他の何か(Pythonなし)から値を貼り付ける場合に便利です。たとえば、環境変数のリストです。あなたがbashファイルを持っているなら、言う

FOO='bar'
CABBAGE='good'

その後、簡単にdict()リテラルに貼り付けてコメントを追加できます。また、反対のことを簡単に行うことができ、他の何かにコピーします。一方、{'FOO': 'bar'}構文は、pythonおよびjsonに非常に固有です。したがって、jsonを頻繁に使用する場合は、二重引用符付きの{}リテラルを使用することをお勧めします。

0
Nick Humrich

また、演算子に一致するトークンはコンストラクター構文、つまりダッシュ化されたキーでは使用できないという事実も考慮してください。

>>> dict(foo-bar=1)
File "<stdin>", line 1
SyntaxError: keyword can't be an expression

>>> {'foo-bar': 1}
{'foo-bar': 1}
0
Brian Whitton