วิธีเริ่มต้น dict ด้วยคีย์จากรายการและค่าว่างใน Python


251

ฉันต้องการได้รับจากสิ่งนี้:

keys = [1,2,3]

สำหรับสิ่งนี้:

{1: None, 2: None, 3: None}

มีวิธี pythonic ทำมันได้หรือไม่

นี่เป็นวิธีที่น่าเกลียดที่จะทำ:

>>> keys = [1,2,3]
>>> dict([(1,2)])
{1: 2}
>>> dict(zip(keys, [None]*len(keys)))
{1: None, 2: None, 3: None}

คำตอบ:


390

dict.fromkeys([1, 2, 3, 4])

นี่เป็นวิธีการเรียนจริงดังนั้นจึงใช้ได้กับคลาสย่อย dict-sub เช่นcollections.defaultdictกัน อาร์กิวเมนต์ตัวเลือกที่สองระบุค่าที่จะใช้สำหรับคีย์ (ค่าเริ่มต้นNone)


154
ระวังการเริ่มต้นกับบางสิ่งที่ไม่แน่นอน: หากคุณโทรเช่นdict.fromkeys([1, 2, 3], [])ปุ่มทั้งหมดจะถูกแมปไปยังรายการเดียวกันและการปรับเปลี่ยนจะทำให้พวกเขาทั้งหมด
charleslparker

8
การเริ่มต้นด้วย{k:[] for k in [1, 2, 3]}ยังคงปลอดภัยแม้ว่า
Aziz Alto

263

ไม่มีใครสนใจที่จะให้คำตอบที่เข้าใจได้?

>>> keys = [1,2,3,5,6,7]
>>> {key: None for key in keys}
{1: None, 2: None, 3: None, 5: None, 6: None, 7: None}

32
ฉันเชื่อว่ามัน backported เป็น 2.7
wim

21
นี่เป็นสิ่งที่ดีและไม่ประสบปัญหาการอ้างอิงที่คำตอบที่ยอมรับนั้นทำได้
charleslparker

นอกจากนี้ยังช่วยให้คุณสามารถกำหนดค่าเริ่มต้น (เช่นFalse)
Neverendingqs

นี่คือความสะอาดทาง Pythonic ที่สุดใน Python3 IMO
เรือประจัญบาน Constantinides

4
การใช้ dict-comp ยังอนุญาตให้ค่าเป็นผลลัพธ์ของการเรียกฟังก์ชัน (ซึ่งสามารถส่งผ่านคีย์เป็นอาร์กิวเมนต์ถ้าต้องการ) - ดังนั้นจึงเป็นกลไกที่ทรงพลังมาก
martineau

56
dict.fromkeys(keys, None)

2
ยอดเยี่ยมฉันต้องการรายการที่ว่างเปล่าdict.fromkeys(keys, [])
muon

12
@muon นั่นคือเกือบจะแน่นอนไม่ได้สิ่งที่คุณต้องการดูความคิดเห็น charleslparker
gerrit

ทำงานใน Python เวอร์ชัน 2.6.6
Mike Finch

2
ระวัง: สิ่งนี้จะเริ่มต้นใช้คำสั่งด้วยปุ่มทั้งหมดชี้ไปที่ค่าเดียว
Mendi Barel

16
>>> keyDict = {"a","b","c","d"}

>>> dict([(key, []) for key in keyDict])

เอาท์พุท:

{'a': [], 'c': [], 'b': [], 'd': []}

1
ในขณะที่รหัสนี้อาจตอบคำถามให้บริบทเพิ่มเติมเกี่ยวกับวิธีการและ / หรือทำไมมันแก้ปัญหาจะปรับปรุงค่าระยะยาวของคำตอบ
Francesco Menzani

4
ชื่อkeyDictเป็นความเข้าใจผิดเช่นบรรทัดแรกของรหัสส่งกลับไม่ได้set dict
ไบรอัน Oakley

10
d = {}
for i in keys:
    d[i] = None

1
ทำไมงูใหญ่ไม่โยนออกข้อผิดพลาดที่ชอบ: TypeError: 'type' object is not iterable?
FaCoffee

1
@FrancescoCastellani เพราะlistเป็นประเภท ยกเว้นว่าคุณมีสิ่งที่ชอบlist = []วิธีการข้างต้นจะให้ข้อผิดพลาดเดียวกันกับคุณเสมอ
smac89

1

ในเวิร์กโฟลว์จำนวนมากที่คุณต้องการแนบค่าเริ่มต้น / ค่าเริ่มต้นสำหรับคีย์ที่กำหนดเองคุณไม่จำเป็นต้องแฮชแต่ละคีย์ล่วงหน้าก่อน collections.defaultdictคุณสามารถใช้ ตัวอย่างเช่น:

from collections import defaultdict

d = defaultdict(lambda: None)

print(d[1])  # None
print(d[2])  # None
print(d[3])  # None

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

สำหรับเวิร์กโฟลว์ที่คุณต้องการการควบคุมคีย์ที่อนุญาตคุณสามารถใช้dict.fromkeysตามคำตอบที่ยอมรับได้:

d = dict.fromkeys([1, 2, 3, 4])
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.