Konversi daftar ke kamus dengan Python

191

Katakanlah saya memiliki daftar adalam Python yang entri-entrinya mudah dipetakan ke kamus. Setiap elemen genap mewakili kunci kamus, dan elemen ganjil berikut adalah nilainya

sebagai contoh,

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

Dan saya ingin mengonversinya ke kamus b, di mana

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

Apa cara terbersih secara sintaksis untuk mencapai ini?

Mike
sumber
3
Kemungkinan duplikat dari Make dictionary from list with python
Jeru Luke

Jawaban:

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

Jika abesar, Anda mungkin ingin melakukan sesuatu seperti yang berikut, yang tidak membuat daftar sementara seperti di atas.

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

Dalam Python 3 Anda juga bisa menggunakan pemahaman dict, tetapi ironisnya saya pikir cara paling sederhana untuk melakukannya adalah dengan range()dan len(), yang biasanya berupa bau kode.

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

Jadi iter()/izip()metode ini mungkin masih yang paling Pythonic di Python 3, meskipun seperti yang dicatat dalam komentar EOL, zip()sudah malas di Python 3 jadi Anda tidak perlu izip().

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

Jika Anda menginginkannya dalam satu baris, Anda harus menipu dan menggunakan titik koma. ;-)

baik hati
sumber
9
... atau sederhananya zip(i, i), dalam Python 3, karena zip()sekarang mengembalikan iterator.
Eric O Lebigot
5
Perhatikan bahwa Python 2.7.3 juga memiliki pemahaman dict
user1438003
56

Jawaban sederhana

Pilihan lain (milik Alex Martelli - sumber ):

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

Catatan terkait

Jika Anda memiliki ini:

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

dan Anda menginginkan ini (setiap elemen daftar memasukkan nilai yang diberikan (2 dalam kasus ini)):

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

kamu bisa memakai:

>>> dict((k,2) for k in a)
{'double': 2, 'bi': 2, 'two': 2, 'duo': 2}
JobJob
sumber
2
Apakah ini hanya untuk Python 3?
Tagar
2
gunakan fromkeys. >>> dict.fromkeys(a, 2) {'bi': 2, 'double': 2, 'duo': 2, 'two': 2}
Gdogg
1
Ini melakukan sesuatu yang lain dari apa yang ditanyakan.
ozn
17

Anda dapat menggunakan pemahaman dict untuk ini dengan cukup mudah:

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

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

Ini sama dengan for loop di bawah ini:

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

Sesuatu yang saya temukan cukup keren, yaitu jika daftar Anda hanya 2 item:

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

Ingat, dict menerima setiap iterable yang berisi iterable di mana setiap item di iterable itu sendiri harus iterable dengan tepat dua objek.

rix
sumber
cepat dan sederhana, hanya untuk menambahkan jika daftar berisi lebih dari dua item kemudian gunakan dict (ls) bukan dict ([ls]). untuk misalnya jika ls = ['a', 'b', 'c', 'd'] maka dict (ls)
ankit tyagi
1
Bagus & ramping "Setiap item dalam iterable itu sendiri harus merupakan iterable dengan tepat dua objek." adalah fakta kunci di sini.
Abhijeet
4

Mungkin bukan yang paling pythonic, tapi

>>> b = {}
>>> for i in range(0, len(a), 2):
        b[a[i]] = a[i+1]
sahhhm
sumber
10
baca tentangenumerate
SilentGhost
5
menghitung tidak memungkinkan Anda menentukan ukuran langkah, tetapi Anda bisa menggunakannya for i, key in enumerate(a[::2]):. Masih unpythonic karena konstruktor dikt dapat melakukan sebagian besar pekerjaan di sini untuk Anda
John La Rooy
@ SilentGhost, gnibbler: terima kasih banyak untuk memperluas wawasan saya! Saya pasti akan memasukkannya sebanyak mungkin di masa depan!
sahhhm
@gnibbler: Bisakah Anda menjelaskan sedikit lebih banyak tentang bagaimana for i, key in enumerate(a[::2]):pendekatan itu bekerja? Nilai pasangan yang dihasilkan akan 0 hellodan 1 1, dan tidak jelas bagi saya bagaimana menggunakannya untuk menghasilkan {'hello':'world', '1':'2'}.
martineau
1
@martineau, Anda benar. Saya pikir saya pasti bermaksudenumerate(a)[::2]
John La Rooy
4

Anda dapat melakukannya dengan cukup cepat tanpa membuat array tambahan, jadi ini akan bekerja bahkan untuk array yang sangat besar:

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

Jika Anda memiliki generator a, lebih baik lagi:

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

Inilah rundown:

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
topkara
sumber
ini akan membuat kamus dengan pasangan kunci dan nilai yang sama ( {'hello':'hello','world':'world','1':'1','2':'2'})
mik
Tidak, semua bekerja dengan baik. Silakan baca lebih cermat. Dikatakan: "Jika Anda memiliki generator ..." Jika Anda tidak memiliki generator, cukup gunakan baris pertama. Yang kedua adalah alternatif yang akan berguna jika Anda memiliki generator alih-alih daftar, seperti yang sering terjadi.
topkara
1

Anda juga dapat melakukannya seperti ini (string ke daftar konversi di sini, lalu konversi ke kamus)

    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
Stefan Gruenwald
sumber
1

Saya juga sangat tertarik untuk memiliki satu-liner untuk konversi ini, sejauh daftar tersebut adalah penginisialisasi default untuk hash di Perl.

Jawaban yang sangat komprehensif diberikan di utas ini -

Milik saya, saya pemula di Python), menggunakan Python 2.7 Generator Expressions , akan menjadi:

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

Oleksiy
sumber
0

Saya tidak yakin apakah ini pythonic, tetapi sepertinya berhasil

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

key_list,value_list = alternate_list(a)
b = dict(zip(key_list,value_list))
Manu
sumber
0

coba kode di bawah ini:

  >>> d2 = dict([('one',1), ('two', 2), ('three', 3)])
  >>> d2
      {'three': 3, 'two': 2, 'one': 1}
muhammed
sumber
0

Anda juga dapat mencoba pendekatan ini menyimpan kunci dan nilai dalam daftar yang berbeda dan kemudian menggunakan metode 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)))

keluaran:

{'test3': '3', 'test1': '1', 'test2': '2', 'test4': '4'}
Aaditya Ura
sumber
0
{x: a[a.index(x)+1] for x in a if a.index(x) % 2 ==0}

result : {'hello': 'world', '1': '2'}
Mahdi Ghelichi
sumber