Pertanyaan Konversikan dua daftar ke dalam kamus dengan Python


Bayangkan Anda memiliki:

keys = ['name', 'age', 'food']
values = ['Monty', 42, 'spam']

Apa cara paling sederhana untuk menghasilkan kamus berikut?

a_dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

748
2017-10-16 19:05


asal


Jawaban:


Seperti ini:

>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}

Voila :-) Secara berpasangan dict konstruktor dan zip fungsinya sangat berguna: https://docs.python.org/3/library/functions.html#func-dict


1384
2017-10-16 19:09



Coba ini:

>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}

Dalam Python 2, itu juga lebih ekonomis dalam konsumsi memori dibandingkan zip.


110
2017-10-16 19:16



Bayangkan Anda memiliki:

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')

Apa cara paling sederhana untuk menghasilkan kamus berikut?

dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}

Paling berkinerja - Python 2.7 dan 3, pemahaman dict:

Peningkatan yang mungkin dalam menggunakan konstruktor dikt adalah dengan menggunakan sintaks asli dari pemahaman dict (bukan pemahaman daftar, seperti yang orang lain telah salah mengartikannya):

new_dict = {k: v for k, v in zip(keys, values)}

Dengan Python 2, zip mengembalikan daftar, untuk menghindari pembuatan daftar yang tidak perlu, gunakan izip sebagai gantinya (alias zip dapat mengurangi perubahan kode ketika Anda pindah ke Python 3).

from itertools import izip as zip

Jadi itu masih:

new_dict = {k: v for k, v in zip(keys, values)}

Python 2, ideal untuk <= 2.6

izip dari itertools menjadi zip dengan Python 3. izip lebih baik daripada zip untuk Python 2 (karena ini menghindari pembuatan daftar yang tidak perlu), dan ideal untuk 2.6 atau lebih rendah:

from itertools import izip
new_dict = dict(izip(keys, values))

Python 3

Dengan Python 3, zip menjadi fungsi yang sama yang ada di itertools modul, jadi itu hanya:

new_dict = dict(zip(keys, values))

Pemahaman dictik akan lebih berkinerja meskipun (lihat review kinerja di akhir jawaban ini).

Hasil untuk semua kasus:

Dalam semua kasus:

>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}

Penjelasan:

Jika kita melihat bantuannya dict kami melihat bahwa dibutuhkan berbagai bentuk argumen:

>>> help(dict)

class dict(object)
 |  dict() -> new empty dictionary
 |  dict(mapping) -> new dictionary initialized from a mapping object's
 |      (key, value) pairs
 |  dict(iterable) -> new dictionary initialized as if via:
 |      d = {}
 |      for k, v in iterable:
 |          d[k] = v
 |  dict(**kwargs) -> new dictionary initialized with the name=value pairs
 |      in the keyword argument list.  For example:  dict(one=1, two=2)

Pendekatan optimal adalah menggunakan iterable sambil menghindari pembuatan struktur data yang tidak perlu. Dalam Python 2, zip membuat daftar yang tidak perlu:

>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

Dengan Python 3, padanannya adalah:

>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]

dan Python 3 zip hanya menciptakan objek iterable:

>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>

Karena kami ingin menghindari pembuatan struktur data yang tidak perlu, kami biasanya ingin menghindari Python 2 zip (karena ini menciptakan daftar yang tidak perlu).

Alternatif yang kurang berkinerja:

Ini adalah ekspresi generator yang diteruskan ke konstruktor dikt:

generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)

atau dengan kata lain:

dict((k, v) for k, v in zip(keys, values))

Dan ini adalah pemahaman daftar yang diteruskan ke konstruktor dikt:

dict([(k, v) for k, v in zip(keys, values)])

Dalam dua kasus pertama, lapisan tambahan dari komputasi non-operatif (dengan demikian tidak perlu) ditempatkan di atas zip yang dapat diulang, dan dalam kasus pemahaman daftar, daftar tambahan tidak perlu dibuat. Saya berharap semua dari mereka kurang berkinerja, dan tentu saja tidak lebih.

Ulasan kinerja:

Dalam 64 bit Python 3.4.3, pada Ubuntu 14.04, dipesan dari yang tercepat ke yang paling lambat:

>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.7836067057214677
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
1.0321204089559615
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
1.0714934510178864
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.6110592018812895
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.7361853648908436

85
2017-11-16 13:54



>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> dict(zip(keys, values))
{'food': 'spam', 'age': 42, 'name': 'Monty'}

29
2017-10-16 19:09



Anda juga dapat menggunakan pemahaman kamus dengan Python ≥ 2.7:

>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> {k: v for k, v in zip(keys, values)}
{'food': 'spam', 'age': 42, 'name': 'Monty'}

26
2018-06-10 20:03



Jika Anda perlu mengubah kunci atau nilai sebelum membuat kamus, maka a ekspresi generator bisa digunakan. Contoh:

>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3])) 

Lihatlah Kode Seperti Pythonista: Python Idiomatic.


13
2017-10-16 20:45



Cara yang lebih alami adalah menggunakan pemahaman kamus

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')    
dict = {keys[i]: values[i] for i in range(len(keys))}

9
2017-11-16 05:03



dengan Python 3.x, berlaku untuk pemahaman dimengerti

keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')

dic = {k:v for k,v in zip(keys, values)}

print(dic)

Lebih lanjut tentang pemahaman dict sini, sebuah contoh ada:

>>> print {i : chr(65+i) for i in range(4)}
    {0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}

8
2018-05-25 13:47



Bagi mereka yang membutuhkan kode sederhana dan tidak terbiasa zip:

List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']

Ini dapat dilakukan dengan satu baris kode:

d = {List1[n]: List2[n] for n in range(len(List1))}

5
2018-03-29 19:13



  • 2018-04-18

Solusi terbaik masih:

In [92]: keys = ('name', 'age', 'food')
...: values = ('Monty', 42, 'spam')
...: 

In [93]: dt = dict(zip(keys, values))
In [94]: dt
Out[94]: {'age': 42, 'food': 'spam', 'name': 'Monty'}

Tranpose:

    lst = [('name', 'Monty'), ('age', 42), ('food', 'spam')]
    keys, values = zip(*lst)
    In [101]: keys
    Out[101]: ('name', 'age', 'food')
    In [102]: values
    Out[102]: ('Monty', 42, 'spam')

2
2018-04-18 02:41