Câu trả lời:
Như thế này:
>>> keys = ['a', 'b', 'c']
>>> values = [1, 2, 3]
>>> dictionary = dict(zip(keys, values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3}
Voila :-) Hàm dict
tạo và zip
hàm của cặp đôi rất hữu ích: https://docs.python.org/3/l Library / fiances.html # func-dict
{thing}
là đường cú pháp để xây dựng một set()
yếu tố có chứa. {*iterable}
là đường cú pháp để xây dựng một set
chứa một số yếu tố. {k:v}
hoặc {**mapping}
sẽ xây dựng một dict
, nhưng về mặt cú pháp khá khác biệt.
{}
cho từ điển. Trong thực tế, nếu chúng ta thử type({})
đầu ra là dict
. Nhưng thực sự, nếu chúng ta cố gắng type({thing})
thì đầu ra là set
.
{k:v for k, v in zip(keys, values)}
. Hóa ra chúng ta có thể. +1.
Hãy tưởng tượng rằng bạn có:
keys = ('name', 'age', 'food') values = ('Monty', 42, 'spam')
Cách đơn giản nhất để sản xuất từ điển sau đây là gì?
dict = {'name' : 'Monty', 'age' : 42, 'food' : 'spam'}
dict
xây dựng vớizip
new_dict = dict(zip(keys, values))
Trong Python 3, zip bây giờ trả về một trình vòng lặp lười biếng và đây là cách tiếp cận hiệu quả nhất.
dict(zip(keys, values))
không đòi hỏi một thời gian tra cứu toàn cầu cho mỗi dict
và zip
, nhưng nó không tạo ra bất kỳ không cần thiết trung dữ liệu cấu trúc hoặc phải đối phó với tra cứu địa phương trong ứng dụng chức năng.
Một ứng cử viên gần gũi để sử dụng hàm tạo dict là sử dụng cú pháp riêng của cách hiểu chính tả (không phải là cách hiểu danh sách , như những người khác đã đặt nhầm):
new_dict = {k: v for k, v in zip(keys, values)}
Chọn mục này khi bạn cần ánh xạ hoặc bộ lọc dựa trên các khóa hoặc giá trị.
Trong Python 2, zip
trả về một danh sách, để tránh tạo một danh sách không cần thiết, izip
thay vào đó , hãy sử dụng (bí danh thành zip có thể giảm các thay đổi mã khi bạn chuyển sang Python 3).
from itertools import izip as zip
Vì vậy, đó vẫn là (2.7):
new_dict = {k: v for k, v in zip(keys, values)}
izip
từ itertools
trở thành zip
trong Python 3. izip
tốt hơn zip cho Python 2 (vì nó tránh việc tạo danh sách không cần thiết) và lý tưởng cho 2.6 trở xuống:
from itertools import izip
new_dict = dict(izip(keys, values))
Trong tất cả trường hợp:
>>> new_dict
{'age': 42, 'name': 'Monty', 'food': 'spam'}
Nếu chúng ta nhìn vào sự giúp đỡ trên, dict
chúng ta thấy rằng nó cần nhiều dạng đối số:
>>> 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)
Cách tiếp cận tối ưu là sử dụng một lần lặp trong khi tránh tạo các cấu trúc dữ liệu không cần thiết. Trong Python 2, zip tạo một danh sách không cần thiết:
>>> zip(keys, values)
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
Trong Python 3, tương đương sẽ là:
>>> list(zip(keys, values))
[('name', 'Monty'), ('age', 42), ('food', 'spam')]
và Python 3 zip
chỉ đơn thuần tạo ra một đối tượng có thể lặp lại:
>>> zip(keys, values)
<zip object at 0x7f0e2ad029c8>
Vì chúng tôi muốn tránh tạo cấu trúc dữ liệu không cần thiết, chúng tôi thường muốn tránh Python 2 zip
(vì nó tạo ra một danh sách không cần thiết).
Đây là một biểu thức trình tạo được truyền cho hàm tạo dict:
generator_expression = ((k, v) for k, v in zip(keys, values))
dict(generator_expression)
hoặc tương đương:
dict((k, v) for k, v in zip(keys, values))
Và đây là một sự hiểu biết danh sách đang được chuyển đến hàm tạo dict:
dict([(k, v) for k, v in zip(keys, values)])
Trong hai trường hợp đầu tiên, một lớp tính toán không hoạt động (do đó không cần thiết) được đặt trên vòng lặp zip và trong trường hợp hiểu danh sách, một danh sách bổ sung được tạo ra một cách không cần thiết. Tôi hy vọng tất cả trong số họ sẽ ít hiệu suất hơn, và chắc chắn không nhiều hơn thế.
Trong 64 bit Python 3.8.2 do Nix cung cấp, trên Ubuntu 16.04, được sắp xếp theo thứ tự từ nhanh nhất đến chậm nhất:
>>> 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))
chiến thắng ngay cả với các bộ khóa và giá trị nhỏ, nhưng đối với các bộ lớn hơn, sự khác biệt về hiệu suất sẽ trở nên lớn hơn.
Một bình luận cho biết:
min
có vẻ như là một cách xấu để so sánh hiệu suất. Chắc chắnmean
và / hoặcmax
sẽ là các chỉ số hữu ích hơn nhiều cho việc sử dụng thực tế.
Chúng tôi sử dụng min
bởi vì các thuật toán này là xác định. Chúng tôi muốn biết hiệu suất của các thuật toán trong các điều kiện tốt nhất có thể.
Nếu hệ điều hành bị treo vì bất kỳ lý do gì, nó không liên quan gì đến những gì chúng tôi đang cố gắng so sánh, vì vậy chúng tôi cần loại trừ những loại kết quả đó khỏi phân tích của chúng tôi.
Nếu chúng ta sử dụng mean
, những loại sự kiện đó sẽ làm sai lệch kết quả của chúng ta rất nhiều và nếu chúng ta sử dụng, max
chúng ta sẽ chỉ nhận được kết quả cực đoan nhất - sự kiện có khả năng bị ảnh hưởng bởi sự kiện đó.
Một bình luận cũng nói:
Trong python 3.6.8, sử dụng các giá trị trung bình, việc hiểu chính tả thực sự vẫn nhanh hơn, khoảng 30% cho các danh sách nhỏ này. Đối với các danh sách lớn hơn (số ngẫu nhiên 10k),
dict
cuộc gọi nhanh hơn khoảng 10%.
Tôi đoán chúng tôi có nghĩa là dict(zip(...
với số ngẫu nhiên 10k. Điều đó có vẻ như một trường hợp sử dụng khá bất thường. Điều này có nghĩa là các cuộc gọi trực tiếp nhất sẽ chiếm ưu thế trong các bộ dữ liệu lớn và tôi sẽ không ngạc nhiên nếu các hệ điều hành bị treo chiếm ưu thế trong bao lâu để chạy thử nghiệm đó, làm lệch số của bạn. Và nếu bạn sử dụng mean
hoặc max
tôi sẽ coi kết quả của bạn là vô nghĩa.
Hãy sử dụng kích thước thực tế hơn trên các ví dụ hàng đầu của chúng tôi:
import numpy
import timeit
l1 = list(numpy.random.random(100))
l2 = list(numpy.random.random(100))
Và chúng tôi thấy ở đây dict(zip(...
thực sự chạy nhanh hơn cho các bộ dữ liệu lớn hơn khoảng 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 microsec cho {k: v for k, v in zip(headList, textList)}
. Tôi sẽ đề nghị trước đây cho dễ đọc và tốc độ. Rõ ràng điều này nhận được ở đối số min () so với mean () cho thời gian.
min
có vẻ như là một cách xấu để so sánh hiệu suất. Chắc chắn mean
và / hoặc max
sẽ là các chỉ số hữu ích hơn nhiều cho việc sử dụng thực tế.
dict
cuộc gọi nhanh hơn khoảng 10%.
Thử cái này:
>>> import itertools
>>> keys = ('name', 'age', 'food')
>>> values = ('Monty', 42, 'spam')
>>> adict = dict(itertools.izip(keys,values))
>>> adict
{'food': 'spam', 'age': 42, 'name': 'Monty'}
Trong Python 2, việc tiêu thụ bộ nhớ cũng tiết kiệm hơn so với zip
.
zip
đã tiết kiệm được bộ nhớ. docs.python.org/3/library/functions.html#zip Trong thực tế, bạn có thể thấy rằng six
sử dụng zip
bằng Python 3 để thay thế itertools.izip
bằng Python 2 pythonhosted.org/six .
Bạn cũng có thể sử dụng khả năng hiểu từ điển trong 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'}
Một cách tự nhiên hơn là sử dụng hiểu từ điển
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dict = {keys[i]: values[i] for i in range(len(keys))}
dict
đối tượng, tại sao nó lại như vậy?, cảm ơn anh bạn.
Nếu bạn cần chuyển đổi các khóa hoặc giá trị trước khi tạo từ điển thì có thể sử dụng biểu thức trình tạo . Thí dụ:
>>> adict = dict((str(k), v) for k, v in zip(['a', 1, 'b'], [2, 'c', 3]))
Hãy xem Code Like a Pythonista: Idiomatic Python .
với Python 3.x, dùng để hiểu chính tả
keys = ('name', 'age', 'food')
values = ('Monty', 42, 'spam')
dic = {k:v for k,v in zip(keys, values)}
print(dic)
Thông tin thêm về nhận thức chính tả ở đây , một ví dụ là có:
>>> print {i : chr(65+i) for i in range(4)}
{0 : 'A', 1 : 'B', 2 : 'C', 3 : 'D'}
Đối với những người cần mã đơn giản và không quen thuộc với zip
:
List1 = ['This', 'is', 'a', 'list']
List2 = ['Put', 'this', 'into', 'dictionary']
Điều này có thể được thực hiện bởi một dòng mã:
d = {List1[n]: List2[n] for n in range(len(List1))}
List1
dài hơnList2
for n in range(len(List1))
là một mô hình chống
Giải pháp tốt nhất vẫn là:
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'}
Chuyển nó:
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')
bạn có thể sử dụng mã dưới đây:
dict(zip(['name', 'age', 'food'], ['Monty', 42, 'spam']))
Nhưng hãy chắc chắn rằng độ dài của các danh sách sẽ giống nhau. Nếu độ dài không giống nhau. Sau đó, chức năng zip biến thành cái dài hơn.
Tôi đã có nghi ngờ này trong khi tôi đang cố gắng giải quyết một vấn đề liên quan đến đồ thị. Vấn đề tôi gặp phải là tôi cần xác định một danh sách kề kề trống và muốn khởi tạo tất cả các nút với một danh sách trống, đó là khi tôi nghĩ làm thế nào để kiểm tra xem nó có đủ nhanh không, ý tôi là nó có đáng để thực hiện thao tác zip không thay vì cặp khóa-giá trị đơn giản. Sau hầu hết thời gian, yếu tố thời gian là một công cụ phá băng quan trọng. Vì vậy, tôi thực hiện thao tác thời gian cho cả hai phương pháp.
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)}')
Với n_nodes = 10.000.000 tôi nhận được,
Lặp lại: 2.825081646999024 Tốc ký: 3.535717916001886
Lặp lại: 5.051560923002398 Tốc ký: 6.255070794999483
Lặp lại: 6.52859034499852 Tốc ký: 8.221581164998497
Lặp lại: 8.683652416999394 Tốc ký: 12.599181543999293
Lặp lại: 11,587241565001023 Tốc ký: 15,27298851100204
Lặp lại: 14.816342867001367 Tốc ký: 17.162912737003353
Lặp lại: 16.645022411001264 Tốc ký: 19.976680120998935
Bạn có thể thấy rõ sau một điểm nhất định, cách tiếp cận lặp lại ở bước thứ n_ vượt qua thời gian của cách tiếp cận tốc ký ở bước thứ n-1_th.
Đây cũng là một ví dụ về việc thêm một giá trị danh sách trong từ điển của bạn
list1 = ["Name", "Surname", "Age"]
list2 = [["Cyd", "JEDD", "JESS"], ["DEY", "AUDIJE", "PONGARON"], [21, 32, 47]]
dic = dict(zip(list1, list2))
print(dic)
luôn đảm bảo "Khóa" (list1) của bạn luôn ở tham số đầu tiên.
{'Name': ['Cyd', 'JEDD', 'JESS'], 'Surname': ['DEY', 'AUDIJE', 'PONGARON'], 'Age': [21, 32, 47]}
Giải pháp như hiểu từ điển với liệt kê:
dict = {item : values[index] for index, item in enumerate(keys)}
Giải pháp như vòng lặp với liệt kê:
dict = {}
for index, item in enumerate(keys):
dict[item] = values[index]
Bạn cũng có thể thử với một danh sách kết hợp hai danh sách;)
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])))
phương pháp không có chức năng 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)}
sẽ không hoạt động. Bạn phải tuyên bố rõ ràng làdict(...)