Từ điển Python: các khóa () và giá trị () luôn luôn theo cùng một thứ tự?


312

Dường như các danh sách được trả về bởi keys()values()các phương thức của từ điển luôn là ánh xạ 1 đến 1 (giả sử từ điển không bị thay đổi giữa việc gọi 2 phương thức).

Ví dụ:

>>> d = {'one':1, 'two': 2, 'three': 3}
>>> k, v = d.keys(), d.values()
>>> for i in range(len(k)):
    print d[k[i]] == v[i]

True
True
True

Nếu bạn không thay đổi từ điển giữa gọi keys()và gọi values(), có sai không khi cho rằng vòng lặp for ở trên sẽ luôn in True? Tôi không thể tìm thấy bất kỳ tài liệu xác nhận điều này.


1
Trong CPython 3.7 (và có lẽ, có lẽ) bạn có thể dựa vào thứ tự lặp của thứ tự chèn từ điển phù hợp. mail.python.org/pipermail/python-dev/2017-December/151283.html
BallpointBen

@BallpointBen nó trong CPython 3.6 trở lên và tất cả các triển khai Python khác bắt đầu với Python 3.7
Boris

Câu trả lời:


353

Tìm thấy điều này:

Nếu items(), keys(), values(), iteritems(), iterkeys(), và itervalues()được gọi là không có thay đổi can thiệp vào từ điển, danh sách sẽ trực tiếp tương ứng.

Mở tài liệu 2.xtài liệu hướng dẫn 3.x .


5
rõ ràng tuyên bố trong tài liệu 3.x rõ ràng hơn: "thứ tự của các mặt hàng sẽ tương ứng trực tiếp"
Shaohua Li

4
Văn bản này bị thiếu trong tài liệu 3.7. Tôi chỉ có thể giả sử vì "Dict giữ trật tự chèn" trong 3.7: mail.python.org/pipermail/python-dev/2017-December/151283.html
EliadL

80

Có, những gì bạn quan sát thực sự là một thuộc tính được bảo đảm - danh sách trả về khóa (), giá trị () và vật phẩm () theo thứ tự phù hợp nếu lệnh không bị thay đổi. iterkeys () & c cũng lặp theo thứ tự như các danh sách tương ứng.


1
Tuy nhiên, trong trường hợp danh sách được thay đổi, Pandas dataframecung cấp một thay thế mà mặt hàng có thể được cập nhật hoặc xóa, và trình tự, các địa điểm chỉ số của các mục trong một dict giống như cấu trúc vẫn cố định.
Ville

48

Có, nó được đảm bảo trong python 2.x :

Nếu các khóa, giá trị và chế độ xem các mục được lặp đi lặp lại mà không có sửa đổi can thiệp vào từ điển, thứ tự của các mục sẽ tương ứng trực tiếp.



6

Tài liệu tham khảo tốt cho các tài liệu. Đây là cách bạn có thể đảm bảo đơn hàng bất kể tài liệu / triển khai:

k, v = zip(*d.iteritems())

1
Trong python3.x, sử dụng dict.items ()
Good Will

4

Theo http://docs.python.org/dev/py3k/l Library / sttyty.html trao đổi thư tín. Tuy nhiên, tôi không thể tìm thấy tài liệu tham khảo cho tài liệu chính thức cho python 2.x cho cùng một điều.

Theo như tôi có thể nói, câu trả lời là có, nhưng chỉ trong python 3.0+


4

Đối với giá trị của nó, một số mã sản xuất được sử dụng nhiều mà tôi đã viết dựa trên giả định này và tôi chưa bao giờ gặp vấn đề với nó. Tôi biết điều đó không làm cho nó đúng mặc dù :-)

Nếu bạn không muốn mạo hiểm, tôi sẽ sử dụng iteritems () nếu bạn có thể.

for key, value in myDictionary.iteritems():
    print key, value

-2

Tôi không hài lòng với những câu trả lời này vì tôi muốn đảm bảo các giá trị được xuất có cùng thứ tự ngay cả khi sử dụng các giá trị khác nhau.

Ở đây bạn chỉ định trả trước thứ tự khóa, các giá trị được trả về sẽ luôn có cùng thứ tự ngay cả khi chính tả thay đổi hoặc bạn sử dụng một lệnh khác.

keys = dict1.keys()
ordered_keys1 = [dict1[cur_key] for cur_key in keys]
ordered_keys2 = [dict2[cur_key] for cur_key in keys]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.