ไวยากรณ์ที่ต้องการสำหรับเริ่มต้น dict คืออะไร: brace literals {} หรือฟังก์ชัน dict ()


212

ฉันใช้ความพยายามในการเรียนรู้ Python และฉันให้ความสำคัญกับมาตรฐานการเข้ารหัสทั่วไป นี่อาจดูเหมือนคำถามที่ไม่มีจู้จี้จุกจิก แต่ฉันพยายามที่จะมุ่งเน้นไปที่แนวทางปฏิบัติที่ดีที่สุดในขณะที่ฉันเรียนรู้ดังนั้นฉันจึงไม่ต้องแก้นิสัย 'เลว' ใด ๆ

ฉันเห็นสองวิธีทั่วไปในการเริ่มต้น dict:

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

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

สิ่งใดที่ถือว่าเป็น "pythonic เพิ่มเติม"? คุณใช้อันไหน ทำไม?


5
คุณใช้บทช่วยสอนอะไร คุณเห็นตัวอย่างที่นำไปสู่ความสับสนที่ไหน
S.Lott

2
ฉันใช้ Python tutorial ดำน้ำใน Python แล้วก็มีบล็อกต่างๆโพสต์ SO และแหล่งข้อมูล Googled อื่น ๆ เอกสารทางการใช้{}ค่อนข้างสม่ำเสมอ แต่ฉันเห็นdict()วิธีชัดเจนมากที่อื่น ฉันเห็นประโยชน์ของไวยากรณ์ชัดเจน แต่การขาดวิธีในเอกสารอย่างเป็นทางการทำให้ฉันสงสัย หลังจากโพสต์สิ่งนี้ฉันได้ดูเอกสารของห้องสมุดdictและพบว่าข้อควรระวังที่สำคัญต้องเป็นตัวระบุที่ถูกต้องเมื่อมีการdictใช้คำสั่งเพื่อเริ่มต้น dict อย่างชัดเจน
daotoad

2
"dict ()" ชัดเจนกว่า "{}" อย่างไร ฉันไม่เข้าใจความสับสนของคุณ ทั้งคู่ดูเหมือนจะชัดเจนสำหรับฉัน คุณสามารถให้คำพูดหรือการอ้างอิงที่ทำให้คุณพูดว่า "dict" คือ "ชัดแจ้ง" และ "{}" ไม่ชัดเจน? คุณคิดว่าความแตกต่างนี้เกิดขึ้นที่ไหน?
S.Lott

21
ความแตกต่างคือการสะกดคำ dict()สะกดเป็น - มันdictใช้ชื่อของประเภท เครื่องมือจัดฟัน ( {}) พึ่งพาเครื่องหมายวรรคตอนเพื่อระบุประเภท
daotoad

คำตอบ:


235

วงเล็บปีกกา การส่งผ่านข้อโต้แย้งคำหลักdict()แม้ว่ามันจะทำงานได้อย่างสวยงามในหลาย ๆ สถานการณ์สามารถเริ่มต้นแผนที่ได้ก็ต่อเมื่อคีย์นั้นเป็นตัวระบุ Python ที่ถูกต้อง

งานนี้:

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

สิ่งนี้จะไม่ทำงาน:

a =                  dict(import='trade', 1=7.8)
>> SyntaxError: invalid syntax  ^

85

ครั้งแรกที่จัดฟันหยิก =มิฉะนั้นคุณใช้เป็นประเด็นความสอดคล้องกับปุ่มที่มีตัวอักษรแปลกในพวกเขาเช่น

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

# Eeep! Breaks if trying to be consistent.
b = dict( 
    a='value',
    b=c='value',
)

11
นี่คือเหตุผลที่คนอาจชอบวิธี dict () สำหรับการเริ่มต้นมันบังคับให้ปุ่มพจนานุกรมเป็นตัวระบุที่ถูกต้องดังนั้นพวกเขาเข้ากันได้กับตัวอย่างเช่น ** kwargs และกุญแจเป็นชื่อแอตทริบิวต์ที่ถูกต้อง
RufusVS

57

รุ่นแรกดีกว่า:

  • มันใช้งานได้กับกุญแจทุกชนิดเช่นคุณสามารถพูด{1: 'one', 2: 'two'}ได้ ตัวแปรที่สองใช้งานได้กับคีย์สตริง (บางส่วน) เท่านั้น การใช้รูปแบบต่าง ๆ ของไวยากรณ์ขึ้นอยู่กับชนิดของคีย์จะไม่สอดคล้องกันไม่จำเป็น
  • มันเร็วกว่า:

    $ 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
  • หากไม่ได้ใช้ไวยากรณ์พิเศษสำหรับตัวอักษรในพจนานุกรมมันอาจไม่มีอยู่จริง

3

ฉันคิดว่าตัวเลือกแรกดีกว่าเพราะคุณจะเข้าถึงค่าในฐานะ ['a'] หรือ ['other'] กุญแจในพจนานุกรมของคุณคือสตริงและไม่มีเหตุผลที่จะแกล้งทำเป็นว่าพวกเขาไม่ใช่ สำหรับฉันแล้วไวยากรณ์ของคำหลักดูฉลาดในตอนแรก แต่คลุมเครือในการค้นหาครั้งที่สอง สิ่งนี้สมเหตุสมผลสำหรับฉันหากคุณทำงานด้วย__dict__และคำหลักจะกลายเป็นคุณลักษณะในภายหลังสิ่งนั้น


3

FYI ในกรณีที่คุณต้องการเพิ่มแอททริบิวไปยังพจนานุกรมของคุณ (สิ่งที่แนบมากับพจนานุกรม แต่ไม่ใช่คีย์) คุณจะต้องใช้แบบฟอร์มที่สอง ในกรณีนี้คุณสามารถเริ่มต้นพจนานุกรมของคุณด้วยปุ่มที่มีอักขระที่กำหนดเองทีละตัวดังนี้:

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

2

บางครั้งdict()ก็เป็นทางเลือกที่ดี:

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) สำหรับ x ในช่วง (0,7)])


2
มีฟังก์ชันแจกแจงที่สามารถทำได้ดีกว่านี้ สำหรับเรื่องนั้นมีประเภท Enum ที่สามารถทำสิ่งที่คุณกำลังทำอยู่ที่นี่ได้ดีขึ้น นอกจากนี้นี่ไม่ใช่คำตอบสำหรับคำถามเลย
dusktreader

2

ฉันมักจะใช้เครื่องมือจัดฟันแบบหยิก อย่างไรก็ตามในบางกรณีที่ฉันกำลังเขียนการทดสอบฉันจะทำการบรรจุ / เปิดออกคำหลักและในกรณีเหล่านี้ dict () สามารถบำรุงรักษาได้มากขึ้นเนื่องจากฉันไม่ต้องการเปลี่ยนแปลง:

a=1,
b=2,

ถึง:

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

นอกจากนี้ยังช่วยในบางสถานการณ์ที่ฉันคิดว่าฉันอาจต้องการเปลี่ยนเป็นอินสแตนซ์ที่มีชื่อหรือคลาสในภายหลัง

ในการดำเนินการของตัวเองเพราะความหลงใหลกับการเพิ่มประสิทธิภาพของฉันและเมื่อฉันไม่เห็นประโยชน์การบำรุงรักษาที่ยิ่งใหญ่โดยเฉพาะฉันจะชอบวงเล็บปีกกา

ในการทดสอบและการใช้งานฉันจะไม่ใช้ dict () หากมีโอกาสที่จะเพิ่มคีย์หรือในอนาคตจะ:

  • ไม่ใช่สตริงเสมอไป
  • ไม่เพียงมีตัวเลขตัวอักษร ASCII และขีดล่าง
  • เริ่มต้นด้วยจำนวนเต็ม ( dict(1foo=2)เพิ่ม SyntaxError)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.