แปลงรายการเป็นพจนานุกรมใน Python


190

สมมติว่าฉันมีรายการaใน Python ที่มีรายการเชื่อมโยงไปยังพจนานุกรมอย่างสะดวก แต่ละองค์ประกอบคู่แสดงถึงกุญแจในพจนานุกรมและองค์ประกอบคี่ต่อไปนี้คือค่า

ตัวอย่างเช่น,

a = ['hello','world','1','2']

และฉันต้องการแปลงเป็นพจนานุกรมbที่

b['hello'] = 'world'
b['1'] = '2'

อะไรคือวิธีที่สะอาดที่สุดในการทำสิ่งนี้ให้สำเร็จ


คำตอบ:


271
b = dict(zip(a[::2], a[1::2]))

หากaมีขนาดใหญ่คุณอาจต้องการทำสิ่งต่อไปนี้ซึ่งไม่ได้ทำรายการชั่วคราวดังกล่าวข้างต้น

from itertools import izip
i = iter(a)
b = dict(izip(i, i))

ใน Python 3 คุณสามารถใช้ dict comprehension ได้ แต่ฉันคิดว่าวิธีที่ง่ายที่สุดในการทำแบบนี้คือการใช้range()และlen()ซึ่งปกติแล้วจะเป็นกลิ่นรหัส

b = {a[i]: a[i+1] for i in range(0, len(a), 2)}

ดังนั้นiter()/izip()วิธีการที่ยังคงน่าจะเป็น Pythonic ที่สุดในหลาม 3 แม้จะเป็นบันทึก EOL ในความคิดเห็นzip()ที่มีอยู่แล้วขี้เกียจในหลาม 3 izip()เพื่อให้คุณไม่จำเป็นต้อง

i = iter(a)
b = dict(zip(i, i))

ถ้าคุณต้องการมันในหนึ่งบรรทัดคุณจะต้องโกงและใช้เครื่องหมายอัฒภาค ;-)


9
... หรือเพียงแค่zip(i, i)ใน Python 3 เนื่องจากzip()ตอนนี้ส่งคืนตัววนซ้ำ
Eric O Lebigot

5
โปรดทราบว่า Python 2.7.3 ยังมีความเข้าใจใน
พจน์

56

คำตอบง่ายๆ

ตัวเลือกอื่น (ความอนุเคราะห์จากAlex Martelli - แหล่งที่มา ):

dict(x[i:i+2] for i in range(0, len(x), 2))

หมายเหตุที่เกี่ยวข้อง

หากคุณมีสิ่งนี้:

a = ['bi','double','duo','two']

และคุณต้องการสิ่งนี้ (แต่ละองค์ประกอบของรายการให้คีย์ค่าที่กำหนด (2 ในกรณีนี้)):

{'bi':2,'double':2,'duo':2,'two':2}

คุณสามารถใช้ได้:

>>> dict((k,2) for k in a)
{'double': 2, 'bi': 2, 'two': 2, 'duo': 2}

2
นี่สำหรับ Python 3 เท่านั้นหรือไม่
Tagar

2
fromkeysใช้ >>> dict.fromkeys(a, 2) {'bi': 2, 'double': 2, 'duo': 2, 'two': 2}
Gdogg

1
นี่คือการทำอย่างอื่นนอกเหนือจากคำถามที่ถาม
ozn

17

คุณสามารถใช้ dict comprehension เพื่อสิ่งนี้ได้อย่างง่ายดาย:

a = ['hello','world','1','2']

my_dict = {item : a[index+1] for index, item in enumerate(a) if index % 2 == 0}

นี่เทียบเท่ากับ for for loop ด้านล่าง:

my_dict = {}
for index, item in enumerate(a):
    if index % 2 == 0:
        my_dict[item] = a[index+1]

10

บางสิ่งที่ฉันคิดว่าเจ๋งมากซึ่งก็คือถ้ารายการของคุณมีความยาวเพียง 2 รายการ:

ls = ['a', 'b']
dict([ls])
>>> {'a':'b'}

โปรดจำไว้ว่า dict ยอมรับ iterable ใด ๆ ที่มี iterable ซึ่งแต่ละไอเท็มใน iterable ต้องเป็น iterable ที่มีสองวัตถุ


อย่างรวดเร็วและง่ายดายเพียงเพิ่มถ้ารายการมีมากกว่าสองรายการจากนั้นใช้ dict (ls) แทน dict ([ls]) เช่นถ้า ls = ['a', 'b', 'c', 'd'] ดังนั้น dict (ls)
ankit tyagi

1
สวย & เงา 'แต่ละรายการใน iterable ต้องเป็น iterable ที่มีสองวัตถุเท่านั้น' เป็นความจริงที่สำคัญที่นี่
Abhijeet

4

อาจจะไม่ไพเราะที่สุด แต่

>>> b = {}
>>> for i in range(0, len(a), 2):
        b[a[i]] = a[i+1]

10
อ่านเกี่ยวกับenumerate
SilentGhost

5
การแจกแจงไม่อนุญาตให้คุณระบุขนาดขั้นตอน แต่คุณสามารถfor i, key in enumerate(a[::2]):ใช้ได้ ยังไม่มีเสียงไพเราะเนื่องจากตัวสร้าง dict สามารถทำงานส่วนใหญ่ให้คุณได้ที่นี่
John La Rooy

@SilentGhost, gnibbler: ขอบคุณมากสำหรับการขยายขอบเขตอันไกลโพ้นของฉัน! ฉันจะต้องรวมมันให้มากที่สุดในอนาคต!
sahhhm

@gnibbler: คุณช่วยอธิบายเพิ่มเติมอีกเล็กน้อยเกี่ยวกับวิธีfor i, key in enumerate(a[::2]):การทำงานของมันได้หรือไม่? ส่งผลให้ค่าคู่จะเป็น0 helloและและก็ไม่มีความชัดเจนให้ฉันวิธีการใช้พวกเขาในการผลิต1 1 {'hello':'world', '1':'2'}
martineau

1
@ Smartineau คุณถูกต้อง ฉันคิดว่าฉันต้องมีความหมายenumerate(a)[::2]
John La Rooy

4

คุณสามารถทำได้อย่างรวดเร็วโดยไม่ต้องสร้างอาร์เรย์เพิ่มเติมดังนั้นจึงสามารถใช้งานได้กับอาร์เรย์ขนาดใหญ่มาก:

dict(izip(*([iter(a)]*2)))

หากคุณมีเครื่องกำเนิดไฟฟ้าaดียิ่งขึ้น:

dict(izip(*([a]*2)))

นี่คือบทสรุป:

iter(h)    #create an iterator from the array, no copies here
[]*2       #creates an array with two copies of the same iterator, the trick
izip(*())  #consumes the two iterators creating a tuple
dict()     #puts the tuples into key,value of the dictionary

สิ่งนี้จะทำให้พจนานุกรมที่มีคู่คีย์และค่าเท่ากัน ( {'hello':'hello','world':'world','1':'1','2':'2'})
มิค

ไม่ทำงานได้ดี โปรดอ่านอย่างละเอียด มันบอกว่า: "ถ้าคุณมีตัวกำเนิด a ... " ถ้าคุณไม่มีตัวสร้างให้ใช้บรรทัดแรก อันที่สองเป็นทางเลือกที่จะมีประโยชน์หากคุณมีตัวสร้างแทนรายการเช่นเดียวกับที่ใช้เวลาส่วนใหญ่
topkara

1

คุณสามารถทำเช่นนี้ได้ (สตริงเพื่อแสดงรายการการแปลงที่นี่จากนั้นแปลงเป็นพจนานุกรม)

    string_list = """
    Hello World
    Goodbye Night
    Great Day
    Final Sunset
    """.split()

    string_list = dict(zip(string_list[::2],string_list[1::2]))

    print string_list

1

ฉันยังสนใจที่จะมีหนึ่งซับในสำหรับการแปลงนี้เนื่องจากรายการดังกล่าวเป็นค่าเริ่มต้นสำหรับแฮชใน Perl

คำตอบที่ครอบคลุมเป็นพิเศษได้รับในหัวข้อนี้ -

Mine one ฉันเป็นมือใหม่ใน Python) โดยใช้Python 2.7 Generator Expressionsจะเป็น:

dict((a[i], a[i + 1]) for i in range(0, len(a) - 1, 2))


0

ฉันไม่แน่ใจว่านี่เป็นงูใหญ่หรือเปล่า แต่ดูเหมือนว่าจะใช้ได้

def alternate_list(a):
   return a[::2], a[1::2]

key_list,value_list = alternate_list(a)
b = dict(zip(key_list,value_list))


0

คุณยังสามารถลองวิธีนี้บันทึกคีย์และค่าต่าง ๆ ในรายการต่าง ๆ จากนั้นใช้เมธอด dict

data=['test1', '1', 'test2', '2', 'test3', '3', 'test4', '4']

keys=[]
values=[]
for i,j in enumerate(data):
    if i%2==0:
        keys.append(j)
    else:
        values.append(j)

print(dict(zip(keys,values)))

เอาท์พุท:

{'test3': '3', 'test1': '1', 'test2': '2', 'test4': '4'}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.