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 :-) dict
Konstruktor dan zip
fungsi berpasangan sangat berguna: https://docs.python.org/3/library/functions.html#func-dict
{thing}
adalah gula sintaksis untuk membangun set()
unsur yang mengandung satu. {*iterable}
adalah gula sintaksis untuk membangun set
beberapa elemen yang mengandung. {k:v}
atau {**mapping}
akan membangun dict
, tapi itu secara sintaksis sangat berbeda.
{}
untuk kamus. Padahal, jika kita coba type({})
outputnya adalah dict
. Tapi memang, jika kita coba type({thing})
maka outputnya adalah set
.
{k:v for k, v in zip(keys, values)}
. Ternyata kita bisa. +1.
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'}
dict
dengan konstruktorzip
new_dict = dict(zip(keys, values))
Dalam Python 3, zip sekarang mengembalikan iterator malas, dan sekarang ini adalah pendekatan yang paling performan.
dict(zip(keys, values))
memang membutuhkan pencarian global satu kali untuk masing-masing dict
dan zip
, tetapi tidak membentuk struktur data menengah yang tidak perlu atau harus berurusan dengan pencarian lokal dalam aplikasi fungsi.
Runner-up yang dekat untuk menggunakan konstruktor dict adalah dengan menggunakan sintaks asli dari pemahaman dict (bukan pemahaman daftar , seperti yang orang lain katakan secara keliru):
new_dict = {k: v for k, v in zip(keys, values)}
Pilih ini saat Anda perlu memetakan atau memfilter berdasarkan kunci atau nilai.
Dalam Python 2, zip
mengembalikan daftar, untuk menghindari membuat 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 (2.7):
new_dict = {k: v for k, v in zip(keys, values)}
izip
dari itertools
menjadi zip
di Python 3. izip
lebih baik daripada zip untuk Python 2 (karena menghindari pembuatan daftar yang tidak perlu), dan ideal untuk 2.6 atau di bawah:
from itertools import izip
new_dict = dict(izip(keys, values))
Dalam semua kasus:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Jika kita melihat bantuan pada dict
kita 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 dengan menggunakan iterable sambil menghindari membuat struktur data yang tidak perlu. Di Python 2, zip membuat daftar yang tidak perlu:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
Dalam Python 3, yang sederajat adalah:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
dan Python 3 zip
hanya menciptakan objek yang dapat diubah:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
Karena kami ingin menghindari membuat struktur data yang tidak perlu, kami biasanya ingin menghindari Python 2 zip
(karena membuat daftar yang tidak perlu).
Ini adalah ekspresi generator yang diteruskan ke konstruktor dikt:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
atau yang setara:
dict((k, v) for k, v in zip(keys, values))
Dan ini adalah daftar pemahaman yang diteruskan ke konstruktor dikt:
dict([(k, v) for k, v in zip(keys, values)])
Dalam dua kasus pertama, lapisan tambahan dari perhitungan non-operasi (dengan demikian tidak perlu) ditempatkan di atas zip iterable, dan dalam hal pemahaman daftar, daftar tambahan tidak perlu dibuat. Saya berharap mereka semua menjadi kurang performan, dan tentu saja tidak lebih.
Dalam 64 bit Python 3.8.2 disediakan oleh Nix, di Ubuntu 16.04, dipesan dari yang tercepat hingga yang paling lambat:
>>> min(timeit.repeat(lambda: dict(zip(keys, values))))
0.6695233230129816
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(keys, values)}))
0.6941362579818815
>>> min(timeit.repeat(lambda: {keys[i]: values[i] for i in range(len(keys))}))
0.8782548159942962
>>>
>>> min(timeit.repeat(lambda: dict([(k, v) for k, v in zip(keys, values)])))
1.077607496001292
>>> min(timeit.repeat(lambda: dict((k, v) for k, v in zip(keys, values))))
1.1840861019445583
dict(zip(keys, values))
menang bahkan dengan set kunci dan nilai yang kecil, tetapi untuk set yang lebih besar, perbedaan dalam kinerja akan menjadi lebih besar.
Seorang komentator berkata:
min
Sepertinya cara yang buruk untuk membandingkan kinerja. Tentunyamean
dan / ataumax
akan menjadi indikator yang jauh lebih berguna untuk penggunaan nyata.
Kami menggunakan min
karena algoritma ini bersifat deterministik. Kami ingin mengetahui kinerja algoritma dalam kondisi terbaik.
Jika sistem operasi hang untuk alasan apa pun, itu tidak ada hubungannya dengan apa yang kami coba bandingkan, jadi kami perlu mengecualikan hasil semacam itu dari analisis kami.
Jika kita menggunakan mean
, peristiwa semacam itu akan sangat max
memengaruhi hasil kita, dan jika kita menggunakan kita hanya akan mendapatkan hasil yang paling ekstrim - yang kemungkinan besar dipengaruhi oleh peristiwa semacam itu.
Seorang komentator juga mengatakan:
Dalam python 3.6.8, menggunakan nilai rata-rata, pemahaman dict memang masih lebih cepat, sekitar 30% untuk daftar kecil ini. Untuk daftar yang lebih besar (10k angka acak),
dict
panggilan ini sekitar 10% lebih cepat.
Saya kira kita maksud dict(zip(...
dengan angka acak 10k. Itu terdengar seperti kasus penggunaan yang tidak biasa. Masuk akal bahwa panggilan paling langsung akan mendominasi dalam dataset besar, dan saya tidak akan terkejut jika OS hang mendominasi mengingat berapa lama waktu yang dibutuhkan untuk menjalankan tes itu, lebih lanjut condong angka Anda. Dan jika Anda menggunakan mean
atau max
saya akan menganggap hasil Anda tidak berarti.
Mari kita gunakan ukuran yang lebih realistis pada contoh teratas kami:
import numpy
import timeit
l1 = list(numpy.random.random(100))
l2 = list(numpy.random.random(100))
Dan kita lihat di sini bahwa dict(zip(...
memang berjalan lebih cepat untuk kumpulan data yang lebih besar sekitar 20%.
>>> min(timeit.repeat(lambda: {k: v for k, v in zip(l1, l2)}))
9.698965263989521
>>> min(timeit.repeat(lambda: dict(zip(l1, l2))))
7.9965161079890095
dict(zip(headList, textList))
& 1,95 \ pm 0,030 mikro untuk {k: v for k, v in zip(headList, textList)}
. Saya akan menyarankan yang pertama untuk keterbacaan dan kecepatan. Jelas ini menjadi argumen min () vs mean () untuk timeit.
min
Sepertinya cara yang buruk untuk membandingkan kinerja. Tentunya mean
dan / atau max
akan menjadi indikator yang jauh lebih berguna untuk penggunaan nyata.
dict
panggilan ini sekitar 10% lebih cepat.
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 dengan zip
.
zip
sudah ekonomis dalam konsumsi memori. docs.python.org/3/library/functions.html#zip Bahkan, Anda dapat melihat bahwa six
menggunakan zip
Python 3 untuk menggantikan itertools.izip
Python 2 pythonhosted.org/six .
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'}
Cara yang lebih alami adalah dengan menggunakan pemahaman kamus
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
dict
objek, mengapa begitu?, terima kasih Bung.
Jika Anda perlu mengubah kunci atau nilai sebelum membuat kamus, maka ekspresi generator dapat digunakan. Contoh:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
Lihatlah Kode Seperti Pythonista: Idiomatic Python .
dengan Python 3.x, berlaku untuk pemahaman dict
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
Lebih lanjut tentang pemahaman dikt di sini , contoh ada di sana:
>>> print {i : chr(65+i) for i in range(4)}
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
Bagi mereka yang membutuhkan kode sederhana dan tidak terbiasa dengan 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))}
List1
lebih lama dariList2
for n in range(len(List1))
merupakan anti-pola
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 itu:
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')
Anda dapat menggunakan kode di bawah ini:
dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))
Tetapi pastikan bahwa panjang daftar akan sama. Jika panjangnya tidak sama, maka fungsi zip akan lebih panjang.
Saya memiliki keraguan ini ketika saya mencoba untuk menyelesaikan masalah yang berhubungan dengan grafik. Masalah yang saya miliki adalah saya perlu mendefinisikan daftar adjacency kosong dan ingin menginisialisasi semua node dengan daftar kosong, saat itulah saya berpikir bagaimana kalau saya periksa apakah cukup cepat, maksud saya jika layak melakukan operasi zip daripada pasangan nilai kunci penugasan sederhana. Bagaimanapun juga, faktor waktu adalah pemecah es yang penting. Jadi saya melakukan operasi timeit untuk kedua pendekatan.
import timeit
def dictionary_creation(n_nodes):
dummy_dict = dict()
for node in range(n_nodes):
dummy_dict[node] = []
return dummy_dict
def dictionary_creation_1(n_nodes):
keys = list(range(n_nodes))
values = [[] for i in range(n_nodes)]
graph = dict(zip(keys, values))
return graph
def wrapper(func, *args, **kwargs):
def wrapped():
return func(*args, **kwargs)
return wrapped
iteration = wrapper(dictionary_creation, n_nodes)
shorthand = wrapper(dictionary_creation_1, n_nodes)
for trail in range(1, 8):
print(f'Itertion: {timeit.timeit(iteration, number=trails)}\nShorthand: {timeit.timeit(shorthand, number=trails)}')
Untuk n_nodes = 10.000.000 saya dapatkan,
Iterasi: 2.825081646999024 Singkatan: 3.535717916001886
Iterasi: 5.051560923002398 Singkatan: 6.255070794999483
Iterasi: 6.52859034499852 Singkatan: 8.221581164998497
Iterasi: 8.683652416999394 Singkatan: 12.599181543999293
Iterasi: 11.587241565001023 Singkatan: 15.27298851100204
Iterasi: 14.816342867001367 Singkatan: 17.162912737003353
Iterasi: 16.645022411001264 Singkatan: 19.976680120998935
Anda dapat melihat dengan jelas setelah titik tertentu, pendekatan iterasi pada langkah n_th mengambil alih waktu yang diambil oleh pendekatan steno pada langkah n-1_th.
Ini juga contoh menambahkan nilai daftar di kamus Anda
list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)
selalu pastikan "Kunci" Anda (list1) selalu di parameter pertama.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
Anda juga dapat mencoba dengan satu daftar yang merupakan kombinasi dari dua daftar;)
a = [1,2,3,4]
n = [5,6,7,8]
x = []
for i in a,n:
x.append(i)
print(dict(zip(x[0], x[1])))
metode tanpa fungsi zip
l1 = [1,2,3,4,5]
l2 = ['a','b','c','d','e']
d1 = {}
for l1_ in l1:
for l2_ in l2:
d1[l1_] = l2_
l2.remove(l2_)
break
print (d1)
{1: 'd', 2: 'b', 3: 'e', 4: 'a', 5: 'c'}
dictionary = {zip(keys, values)}
itu tidak akan berhasil. Anda harus secara eksplisit mendeklarasikan sebagaidict(...)