Urutan kunci dalam kamus

103

Kode:

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

print l

Ini cetakan ['a', 'c', 'b']. Saya tidak yakin bagaimana metode keys()menentukan urutan kata kunci dalam l . Namun, saya ingin bisa mendapatkan kembali kata kunci dalam urutan yang "benar". Urutan yang tepat tentu saja akan membuat daftar ['a', 'b', 'c'].

persegi panjang
sumber
4
Jika kamus Python seperti kebanyakan, mereka sebenarnya adalah tabel hash. Antara lain, itu berarti urutan kunci tidak dijamin atau bahkan ditentukan. Secara khusus, ia tidak akan mengingat urutan penambahan kunci.
cHao
4
@cHao: Ini pada dasarnya berarti bahwa program Anda akan menjadi tidak pasti jika Anda mengulang elemen dalam kamus?
HelloGoodbye
5
@HelloGoodbye: Saya tidak akan bertindak sejauh itu; masih ada perilaku yang bisa diprediksi di sana. Setiap iterasi penuh melihat tepat satu dari setiap pasangan kunci / nilai. Dan di sebagian besar bahasa, Anda bahkan akan melihatnya dalam urutan yang sama setiap saat. Kecuali jika dokumen tersebut menjamin pesanan tertentu, Anda tidak boleh mengandalkannya sebagai pesanan yang Anda inginkan. (Beberapa bahasa (seperti Perl) sebenarnya akan mengacak urutan sedikit - diduga untuk alasan keamanan, tetapi saya pikir itu benar-benar hanya untuk melepaskan Anda dari kebiasaan mengandalkan perilaku yang tidak ditentukan. :) Saya rasa Python tidak cukup itu jahat, tapi eh ...)
cHao
1
Urutannya akan sama asalkan dict belum diubah. Dari manual: "Jika item (), keys (), values ​​(), iteritems (), iterkeys (), dan itervalues ​​() dipanggil tanpa modifikasi intervensi ke kamus, daftar akan langsung sesuai. Ini memungkinkan pembuatan dari (nilai, kunci) pasangan menggunakan zip (): pasangan = zip (d.values ​​(), d.keys ()). "
steveayre
2
@sfranky Saya pikir yang dimaksud steveayre adalah bahwa urutannya sama antara apa yang Anda peroleh dengan menggunakan metode berbeda yang disebutkan, tidak sama dengan ordrer tempat elemen ditulis.
bli

Jawaban:

79

Anda dapat menggunakan OrderedDict (membutuhkan Python 2.7) atau yang lebih tinggi.

Juga, perhatikan itu OrderedDict({'a': 1, 'b':2, 'c':3})tidak akan berfungsi karena dictAnda membuat dengan {...}telah melupakan urutan elemen. Sebaliknya, Anda ingin menggunakan OrderedDict([('a', 1), ('b', 2), ('c', 3)]).

Seperti yang disebutkan dalam dokumentasi, untuk versi yang lebih rendah dari Python 2.7, Anda dapat menggunakan resep ini .

Abhinav Gupta
sumber
18
Perlu diingat, urutan OrderedDict adalah urutan penyisipan ; kunci hanya akan keluar dalam urutan abjad jika Anda memasukkannya seperti itu.
Hugh Bothwell
itu yang dia tunjukkan sebagai contoh yang disederhanakan; itu mungkin atau mungkin tidak ada hubungannya dengan bagaimana dia sebenarnya berencana untuk menggunakannya. Saya sebelumnya bertemu orang-orang yang mengharapkan OrderedDict untuk mengembalikan penyisipan sewenang-wenang dalam urutan yang diurutkan, jadi saya merasa saya harus menunjukkan ini.
Hugh Bothwell
124

Python 3.7+

Dalam Python 3.7.0 , sifat pelestarian urutan penyisipan dictobjek telah dinyatakan sebagai bagian resmi dari spesifikasi bahasa Python. Oleh karena itu, Anda dapat bergantung padanya.

Python 3.6 (CPython)

Mulai Python 3.6, untuk implementasi CPython dari Python, kamus mempertahankan urutan penyisipan secara default. Ini dianggap sebagai detail implementasi; Anda tetap harus menggunakan collections.OrderedDictjika Anda menginginkan urutan penyisipan yang dijamin di seluruh implementasi Python lainnya.

Python> = 2.7 dan <3.6

Gunakan collections.OrderedDictkelas ketika Anda membutuhkan dictyang mengingat urutan item yang dimasukkan.

Eugene Yarmash
sumber
51
>>> print sorted(d.keys())
['a', 'b', 'c']

Gunakan fungsi yang diurutkan , yang mengurutkan iterable yang diteruskan.

The .keys()Metode mengembalikan kunci dalam urutan yang sewenang-wenang.

Mike Lewis
sumber
12
Ini tidak berfungsi jika Anda menginginkan pesanan asli dan tidak diurutkan.
Simon
13

Dari http://docs.python.org/tutorial/datastructures.html :

"Metode keys () dari objek kamus mengembalikan daftar semua kunci yang digunakan dalam kamus, dalam urutan arbitrer (jika Anda ingin itu diurutkan, cukup terapkan fungsi diurutkan () ke sana)."


sumber
12

Cukup urutkan daftar saat Anda ingin menggunakannya.

l = sorted(d.keys())
Drew
sumber
1

Meskipun urutannya tidak masalah karena kamusnya adalah hashmap. Itu tergantung pada urutan bagaimana itu didorong:

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()))

output:
untuk string abbc, kuncinya adalah dict_keys (['a', 'b', 'c'])
untuk string cbab, kuncinya adalah dict_keys (['c', 'b', 'a'])

zehai
sumber
1
Kamus dalam python adalah penyisipan yang dipesan hanya dari versi 3.6+ periksa ini
Crivella