Apa sintaks yang disukai untuk menginisialisasi fungsi dict: curly brace literals {} atau dict ()?

212

Saya berupaya untuk belajar Python, dan saya memperhatikan standar pengkodean umum. Ini mungkin tampak seperti pertanyaan yang sia-sia, tetapi saya mencoba untuk fokus pada praktik terbaik yang saya pelajari, jadi saya tidak perlu melepaskan kebiasaan 'buruk'.

Saya melihat dua metode umum untuk menginisialisasi dict:

a = {
    'a': 'value',
    'another': 'value',
}

b = dict( 
    a='value',
    another='value',
)

Mana yang dianggap "lebih pythonic"? Yang mana yang kamu gunakan? Mengapa?

daotoad
sumber
5
Tutorial apa yang Anda gunakan? Di mana Anda melihat contoh yang menyebabkan kebingungan?
S.Lott
2
Yah, saya telah menggunakan tutorial Python, Menyelam ke Python dan kemudian berbagai blog, posting SO dan sumber daya Google lainnya. Dokumen resmi menggunakan {}cukup seragam, tetapi saya melihat banyak dict()pendekatan eksplisit di tempat lain. Saya bisa melihat manfaat dari sintaksis eksplisit, tetapi tidak adanya pendekatan dalam dokumen resmi membuat saya curiga. Setelah memposting ini, saya melihat dokumen perpustakaan untuk dictdan menemukan peringatan bahwa kunci harus pengidentifikasi yang valid ketika secara eksplisit dictdigunakan untuk menginisialisasi dict.
daotoad
2
Bagaimana "dikt ()" lebih eksplisit daripada "{}"? Saya tidak mengerti kebingungan Anda. Keduanya tampak eksplisit bagi saya. Bisakah Anda memberikan penawaran atau referensi yang membuat Anda mengatakan "dikt" adalah "eksplisit" dan "{}" tidak eksplisit? Menurut Anda di mana perbedaan ini muncul?
S.Lott
21
Perbedaannya adalah ejaan. dict()dieja - ini dictmenggunakan nama tipe. Kawat gigi ( {}) mengandalkan tanda baca untuk mengidentifikasi jenisnya.
daotoad

Jawaban:

235

Kurung kurawal. Melewati argumen kata kunci dict(), meskipun berfungsi dengan baik dalam banyak skenario, hanya dapat menginisialisasi peta jika kunci adalah pengidentifikasi Python yang valid.

Ini bekerja:

a = {'import': 'trade', 1: 7.8}
a = dict({'import': 'trade', 1: 7.8})

Ini tidak akan berfungsi:

a =                  dict(import='trade', 1=7.8)
>> SyntaxError: invalid syntax  ^
Wai Yip Tung
sumber
85

Yang pertama, kurung kurawal. Jika tidak, Anda mengalami masalah konsistensi dengan kunci yang memiliki karakter aneh di dalamnya, seperti =.

# Works fine.
a = {
    'a': 'value',
    'b=c': 'value',
}

# Eeep! Breaks if trying to be consistent.
b = dict( 
    a='value',
    b=c='value',
)
Amber
sumber
11
Inilah sebabnya mengapa orang mungkin lebih suka metode dict () untuk inisialisasi, itu memaksa kunci kamus untuk menjadi pengidentifikasi yang valid, sehingga mereka kompatibel dengan, misalnya, ** kwargs, dan kunci adalah nama atribut yang valid.
RufusVS
57

Versi pertama lebih disukai:

  • Ini berfungsi untuk semua jenis kunci, jadi Anda bisa, misalnya, mengatakan {1: 'one', 2: 'two'}. Varian kedua hanya berfungsi untuk (beberapa) kunci string. Menggunakan berbagai jenis sintaks tergantung pada jenis kunci akan menjadi inkonsistensi yang tidak perlu.
  • Lebih cepat:

    $ python -m timeit "dict(a='value', another='value')"
    1000000 loops, best of 3: 0.79 usec per loop
    $ python -m timeit "{'a': 'value','another': 'value'}"
    1000000 loops, best of 3: 0.305 usec per loop
  • Jika sintaks khusus untuk literal kamus tidak dimaksudkan untuk digunakan, itu mungkin tidak akan ada.
stephan
sumber
3

Saya pikir opsi pertama lebih baik karena Anda akan mengakses nilai sebagai ['a'] atau ['lain']. Kunci dalam kamus Anda adalah string, dan tidak ada alasan untuk berpura-pura tidak. Bagi saya sintaksis kata kunci terlihat pintar pada awalnya, tetapi tidak jelas pada tampilan kedua. Ini hanya masuk akal bagi saya jika Anda bekerja dengan __dict__, dan kata kunci akan menjadi atribut nanti, seperti itu.

Dibagi nol
sumber
3

FYI, jika Anda perlu menambahkan atribut ke kamus Anda (hal-hal yang dilampirkan ke kamus, tetapi bukan salah satu kunci), maka Anda akan membutuhkan bentuk kedua. Dalam hal ini, Anda dapat menginisialisasi kamus Anda dengan kunci yang memiliki karakter arbitrer, satu per satu, seperti:

    class mydict(dict): pass
    a = mydict()        
    a["b=c"] = 'value'
    a.test = False
Joshua Richardson
sumber
2

Terkadang dict()merupakan pilihan yang baik:

a=dict(zip(['Mon','Tue','Wed','Thu','Fri'], [x for x in range(1, 6)]))

mydict=dict(zip(['mon','tue','wed','thu','fri','sat','sun'],

[random.randint (0,100) untuk rentang x (0,7)]))

Deqing
sumber
2
Ada fungsi enumerasi yang bisa melakukan ini dengan lebih baik. Untuk itu, ada tipe Enum yang dapat melakukan apa yang Anda lakukan di sini dengan lebih baik. Juga, ini sama sekali bukan jawaban untuk pertanyaan itu.
dusktreader
2

Saya hampir selalu menggunakan kurung kurawal; namun, dalam beberapa kasus ketika saya sedang menulis tes, saya melakukan pengepakan / pembongkaran kata kunci, dan dalam kasus ini dict () jauh lebih mudah dikelola, karena saya tidak perlu mengubah:

a=1,
b=2,

untuk:

'a': 1,
'b': 2,

Ini juga membantu dalam beberapa keadaan di mana saya pikir saya mungkin ingin mengubahnya menjadi instanceeduple atau kelas contoh di lain waktu.

Dalam implementasi itu sendiri, karena obsesi saya pada optimasi, dan ketika saya tidak melihat manfaat pemeliharaan yang sangat besar, saya akan selalu memilih kurung kurawal.

Dalam tes dan implementasinya, saya tidak akan pernah menggunakan dict () jika ada kemungkinan bahwa kunci ditambahkan kemudian, atau di masa depan, akan:

  • Tidak selalu berupa string
  • Tidak hanya berisi angka, surat dan garis bawah ASCII
  • Mulai dengan integer ( dict(1foo=2)menimbulkan SyntaxError)
pengguna989266
sumber