Sözlüklerdeki anahtarların sırası


106

Kod:

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

print l

Bu baskı ['a', 'c', 'b']. Yöntemin lkeys() içindeki anahtar kelimelerin sırasını nasıl belirlediğinden emin değilim . Bununla birlikte, anahtar kelimeleri "uygun" sırada geri alabilmek istiyorum. Elbette doğru sıra listeyi oluşturacaktır .['a', 'b', 'c']


4
Python sözlükleri çoğu gibiyse, aslında karma tablolardır. Diğer şeylerin yanı sıra, bu, anahtarların sırasının garanti edilmediği ve hatta belirtilmediği anlamına gelir. Özellikle, anahtarların eklendiği sırayı hatırlamaz.
cHao

4
@cHao: Bu aslında, bir sözlükteki öğelerin üzerinden geçerseniz programınızın belirsiz olacağı anlamına mı geliyor?
HelloGoodbye

5
@HelloGoodbye: O kadar ileri gitmezdim; orada hala çok tahmin edilebilir davranışlar var. Her tam yineleme, her anahtar / değer çiftinden tam olarak birini görür. Ve çoğu dilde, her seferinde aynı sırayla bile göreceksiniz. Dokümanlar belirli bir siparişi garanti etmedikçe, bunun istediğiniz sipariş olduğuna güvenmemelisiniz. (Bazı diller (Perl gibi) aslında sıralamayı biraz rasgele dağıtacaktır - iddiaya göre güvenlik nedenleriyle, ancak bunun gerçekten sadece sizi belirsiz davranışlara güvenme alışkanlığından kurtulmak için olduğunu düşünüyorum . :) Python'un pek olduğunu düşünmüyorum o kötü, ama eh ...)
cHao

1
Emir değiştirilmediği sürece sıra aynı olacaktır. Kılavuzdan: "Eğer sözlükte araya giren değişiklikler olmadan items (), keys (), values ​​(), iteritems (), iterkeys () ve itervalues ​​() çağrılırsa, listeler doğrudan karşılık gelecektir. zip () kullanan (değer, anahtar) çifti: çiftler = zip (d.values ​​(), d.keys ()). "
steveayre

2
@sfranky Sanırım steveayre'nin kastettiği, sıranın, öğelerin yazıldığı ordrer ile aynı değil, bahsedilen farklı yöntemler kullanılarak elde edilenler arasında aynı olmasıdır.
bli

Yanıtlar:


81

Sen kullanabilirsiniz OrderedDict (gerektirir Python 2.7) veya daha yüksek.

Ayrıca, oluşturduğunuz öğe öğelerin sırasını çoktan unuttuğundan, OrderedDict({'a': 1, 'b':2, 'c':3})bunun işe yaramayacağını unutmayın . Bunun yerine kullanmak istiyorsunuz .dict{...}OrderedDict([('a', 1), ('b', 2), ('c', 3)])

Belgelerde belirtildiği gibi, Python 2.7'den daha düşük sürümler için bu tarifi kullanabilirsiniz .


19
Bir OrderedDict'in sırasının kampanya siparişi olduğunu unutmayın; Anahtarlar yalnızca bu şekilde yerleştirirseniz alfabetik sırada çıkar.
Hugh Bothwell

basitleştirilmiş bir örnek olarak gösterdiği şey ; gerçekte nasıl kullanmayı planladığıyla herhangi bir ilişkisi olabilir veya olmayabilir. Daha önce OrderedDict'in rastgele eklemeleri sıralı sırayla döndürmesini bekleyen insanlarla karşılaştım ve bu yüzden bunu belirtmem gerektiğini hissettim.
Hugh Bothwell

131

Python 3.7+

Python 3.7.0'da , dictnesnelerin ekleme sırası koruma doğası , Python dil spesifikasyonunun resmi bir parçası olarak ilan edilmiştir. Bu nedenle ona güvenebilirsiniz.

Python 3.6 (CPython)

Python 3.6'dan itibaren, Python'un CPython uygulaması için, sözlükler varsayılan olarak ekleme sırasını korur . Bu bir uygulama ayrıntısı olarak kabul edilir; collections.OrderedDictPython'un diğer uygulamalarında garanti edilen ekleme sıralaması istiyorsanız yine de kullanmalısınız .

Python> = 2.7 ve <3.6

Eklenen öğelerin sırasını hatırlayan collections.OrderedDictbir ihtiyacınız olduğunda sınıfı kullanın dict.


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

İletilen yinelenebilirliği sıralayan sıralı işlevi kullanın .

.keys()Yöntem, isteğe göre bir sırada anahtarları geri döndürür.


12
Orijinal sırayı istiyorsanız ve sıralanmadıysa bu işe yaramaz.
Simon

13

Gönderen http://docs.python.org/tutorial/datastructures.html :

"Bir sözlük nesnesinin keys () yöntemi, sözlükte kullanılan tüm anahtarların listesini rasgele sırayla döndürür (sıralanmasını istiyorsanız, sıralı () işlevini uygulayın)."


12

Listeyi kullanmak istediğinizde sıralamanız yeterli.

l = sorted(d.keys())

1

Sözlük hashmap olduğundan sıra önemli olmasa da. Nasıl itildiğine bağlıdır:

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

çıktı:
abbc dizesi için, cbab dizesi için anahtarlar dict_keys (['a', 'b', 'c'])
, anahtarlar dict_keys (['c', 'b', 'a'])


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.