Thứ tự các khóa trong từ điển


101

Mã:

d = {'a': 0, 'b': 1, 'c': 2}
l = d.keys()

print l

Bản in này ['a', 'c', 'b']. Tôi không chắc về cách phương pháp keys()xác định thứ tự của các từ khóa trong l . Tuy nhiên, tôi muốn có thể truy xuất các từ khóa theo thứ tự "thích hợp". Thứ tự thích hợp tất nhiên sẽ tạo ra danh sách ['a', 'b', 'c'].


3
Nếu các từ điển Python giống như hầu hết, chúng thực sự là bảng băm. Trong số những thứ khác, điều đó có nghĩa là thứ tự của các phím không được đảm bảo hoặc thậm chí được chỉ định. Đặc biệt, nó sẽ không nhớ thứ tự các khóa được thêm vào.
cHao,

3
@cHao: Điều này về bản chất có nghĩa là chương trình của bạn sẽ không xác định được nếu bạn lặp lại các phần tử trong từ điển?
HelloGoodbye

4
@HelloGoodbye: Tôi sẽ không đi xa như vậy; vẫn có những hành vi rất dễ đoán ở đó. Mỗi lần lặp lại đầy đủ sẽ thấy chính xác một trong mỗi cặp khóa / giá trị. Và trong hầu hết các ngôn ngữ, bạn thậm chí sẽ thấy chúng theo thứ tự mỗi lần. Tuy nhiên, trừ khi các tài liệu đảm bảo một đơn đặt hàng cụ thể, bạn không nên tin rằng đó là đơn đặt hàng bạn muốn. (Một số ngôn ngữ (như Perl) thực sự sẽ ngẫu nhiên hóa thứ tự một chút - được cho là vì lý do bảo mật, nhưng tôi nghĩ nó thực sự chỉ để giúp bạn thoát khỏi thói quen dựa vào hành vi không xác định. :) Tôi không nghĩ Python khá ác vậy, nhưng eh ...)
cHao

1
Thứ tự sẽ như cũ với điều kiện không được sửa đổi. Từ hướng dẫn: "Nếu các mục (), khóa (), giá trị (), iteritems (), iterkeys () và itervalues ​​() được gọi mà không có sửa đổi can thiệp vào từ điển, danh sách sẽ trực tiếp tương ứng. Điều này cho phép tạo trong số các cặp (giá trị, khóa) sử dụng zip (): cặp = zip (d.values ​​(), d.keys ()). "
steveayre

2
@sfranky Tôi nghĩ ý của steveayre là thứ tự giống nhau giữa những gì bạn nhận được bằng cách sử dụng các phương pháp khác nhau được đề cập, không giống với thứ tự mà các phần tử được viết.
Bli

Câu trả lời:


78

Bạn có thể sử dụng OrderedDict (yêu cầu Python 2.7) hoặc cao hơn.

Ngoài ra, lưu ý rằng điều đó OrderedDict({'a': 1, 'b':2, 'c':3})sẽ không hoạt động vì dictbạn tạo với {...}đã quên thứ tự của các phần tử. Thay vào đó, bạn muốn sử dụng OrderedDict([('a', 1), ('b', 2), ('c', 3)]).

Như đã đề cập trong tài liệu, đối với các phiên bản thấp hơn Python 2.7, bạn có thể sử dụng công thức này .


18
Hãy nhớ rằng, thứ tự của OrderedDict là thứ tự chèn ; các phím sẽ chỉ xuất hiện theo thứ tự bảng chữ cái nếu bạn chèn chúng theo cách đó.
Hugh Bothwell

đó là những gì anh ấy thể hiện như một ví dụ đơn giản hóa; nó có thể có hoặc không liên quan đến cách anh ta thực sự định sử dụng nó. Trước đây tôi đã gặp những người mong đợi OrderedDict trả lại các phần chèn tùy ý theo thứ tự được sắp xếp và vì vậy tôi cảm thấy mình nên chỉ ra điều này.
Hugh Bothwell

118

Python 3.7+

Trong Python 3.7.0 , bản chất bảo toàn thứ tự chèn của dictcác đối tượng đã được khai báo là một phần chính thức của đặc tả ngôn ngữ Python. Do đó, bạn có thể phụ thuộc vào nó.

Python 3.6 (CPython)

Kể từ Python 3.6, để triển khai CPython của Python, các từ điển duy trì thứ tự chèn theo mặc định. Đây được coi là một chi tiết thực hiện mặc dù; bạn vẫn nên sử dụng collections.OrderedDictnếu bạn muốn thứ tự chèn được đảm bảo trên các triển khai khác của Python.

Python> = 2,7 và <3,6

Sử dụng collections.OrderedDictlớp khi bạn cần một lớp dictghi nhớ thứ tự các mục được chèn.


48
>>> print sorted(d.keys())
['a', 'b', 'c']

Sử dụng hàm đã sắp xếp để sắp xếp có thể lặp được chuyển vào.

Các .keys()phương thức trả về các phím trong một trật tự tùy ý.


12
Điều này không hoạt động nếu bạn muốn thứ tự ban đầu và nó không được sắp xếp.
Simon

12

Chỉ cần sắp xếp danh sách khi bạn muốn sử dụng nó.

l = sorted(d.keys())

12

Từ http://docs.python.org/tutorial/datastructures.html :

"Phương thức keys () của một đối tượng từ điển trả về danh sách tất cả các khóa được sử dụng trong từ điển, theo thứ tự tùy ý (nếu bạn muốn nó được sắp xếp, chỉ cần áp dụng hàm sorted () cho nó)."


1

Mặc dù thứ tự không quan trọng vì từ điển là hashmap. Nó phụ thuộc vào thứ tự cách nó được đẩy vào:

s = 'abbc'
a = 'cbab'

def load_dict(s):
    dict_tmp = {}
    for ch in s:
        if ch in dict_tmp.keys():
            dict_tmp[ch]+=1
        else:
            dict_tmp[ch] = 1
    return dict_tmp

dict_a = load_dict(a)
dict_s = load_dict(s)
print('for string %s, the keys are %s'%(s, dict_s.keys()))
print('for string %s, the keys are %s'%(a, dict_a.keys()))

đầu ra:
đối với chuỗi abbc, các khóa là dict_keys (['a', 'b', 'c'])
đối với string cbab, các khóa là dict_keys (['c', 'b', 'a'])


1
Từ điển trong python được chèn chỉ đặt hàng từ phiên bản 3.6+ kiểm tra này
Crivella
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.