Dikteyi OrderedDict'e dönüştürme


138

collections.OrderedDictSınıfı kullanırken biraz sorun yaşıyorum . Ahududu Pi için Debian dağıtım Raspbian Python 2.7 kullanıyorum. Bir metin-macera için karşılaştırma (yan yana) için iki sözlük yazdırmaya çalışıyorum. Doğru bir şekilde karşılaştırmak için sipariş gereklidir. Ne denesem deneyim, sözlükler her zamanki gibi düzenlenmemiş şekilde yazdırılır.

RPi üzerinde yaptığım zaman:

import collections

ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship
# OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])

Açıkçası doğru olmayan bir şey var çünkü fonksiyon çağrısını yazdırıyor ve anahtarları ve değer gruplarını iç içe bir listeye koyuyor ...

Bilgisayarımda benzer bir şey çalıştırarak aldım:

import collections

Joe = {"Age": 28, "Race": "Latino", "Job": "Nurse"}
Bob = {"Age": 25, "Race": "White", "Job": "Mechanic", "Random": "stuff"}

#Just for clarity:
Joe = collections.OrderedDict(Joe)
Bob = collections.OrderedDict(Bob)

print Joe
# OrderedDict([('Age', 28), ('Race', 'Latino'), ('Job', 'Nurse')])
print Bob
# OrderedDict([('Age', 25), ('Race', 'White'), ('Job', 'Mechanic'), ('Random', 'stuff')])

Bu sefer düzenli, ama diğer şeyleri de basmıyor olmalı değil mi? (Listeye koymak ve işlev çağrısını göstermek.)

Hatamı nerede yapıyorum? Python'un pi versiyonu ile ilgisi olmamalı çünkü sadece Linux versiyonu.


3
Not: OrderedDictalfasayısal anahtar sırasına göre değil, kampanya siparişine göre sıralanır.
el.pescado

Yanıtlar:


214

Sen bir sözlük oluşturuyorsunuz ilk sonra bu sözlüğü geçen OrderedDict. Python <3.6 (*) sürümleri için , bunu yaptığınızda sipariş artık doğru olmayacaktır. dictdoğal olarak sipariş edilmemiştir.

Bunun yerine bir dizi tuple geçirin:

ship = [("NAME", "Albatross"),
        ("HP", 50),
        ("BLASTERS", 13),
        ("THRUSTERS", 18),
        ("PRICE", 250)]
ship = collections.OrderedDict(ship)

Yazdırdığınızda gördüğünüz OrderedDictşey temsilidir ve tamamen doğrudur. OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])sadece tekrarlanabilir bir sunumda , içeriğin ne olduğunu gösterir OrderedDict.


(*) : CPython 3.6 uygulamasında, dicttür, ekleme sırasını korumanın mutlu yan etkisine sahip, bellek açısından daha verimli bir iç yapı kullanacak şekilde güncelleştirildi ve uzantıda, soruda gösterilen kod sorunsuz çalışıyor. Python 3.7'den itibaren, Python dil belirtimi , tüm Python uygulamalarının bu davranışı izlemesini gerektirecek şekilde güncellenmiştir. Ayrıntılar için bu diğer cevabım ve neden OrderedDict()bazı durumlarda hala kullanmak isteyebileceğinize bakın .


Tamam yani OrderedDict sözlük benim için OLUŞTURACAK? Ayrıca, çoğaltılabilir temsil olmadan yazdırmak için sadece OrderedDict kullanılan değişkeni yazdırabilir miyim? yani: print ship ?? Thanks :)
pythonpiboy

3
Soru: Tarif ettiğiniz şekilde, OrderedDict sıralı bir "liste" yapıyor. Bu amacı yenmez mi? Anahtarlar ve değerlerle sözlükler değil, sadece bir elemanlar listesi yaratıyor ...
pythonpiboy

9
Tür her ikisi gibi davranır; düzeni koruyan bir eşleme. Siparişle bir tane oluşturmak için, öğeleri sırayla vermeniz gerekir . Standart bir dikte (PyPI veya Python 3.6+ dışında herhangi bir şeyde) bunu yapamayacağı için, bunun yerine tuples listesini verirsiniz. Bir kez OrderedDictedilir oluşturulan bu olduğunu bir sözlük.
Martijn Pieters

4
Karışıklık gibi bir şey, sadece bir siparişi korumak yerine bir OrdereredDict'in bir siparişi "uyguladığını" varsaymaktan kaynaklanıyor. Kesinlikle yaratıldığında girdiyi sıralayacağını varsaydım - ya da items () işlevi, ne zaman takıldıklarına bakılmaksızın sıralı öğeleri döndüreceğini varsaydım. Bunun yerine, sağladığınız siparişi tutar.
whiterook6

2
@ whiterook6: öyle değil sıralı Sözlük hayır. Sıralı bir sözlük, anahtar / değer çiftlerinin sırasını kaydeden ve bu çiftleri yeniden sıralamanızı sağlayan bir sözlük. Bunu sıralı diziler olan listelerle karşılaştırın .
Martijn Pieters

36

Dict'inizin tanımlandığı bu kod bölümünü düzenleyemiyorsanız, yine de istediğiniz gibi, istediğiniz gibi sipariş edebilirsiniz:

from collections import OrderedDict

order_of_keys = ["key1", "key2", "key3", "key4", "key5"]
list_of_tuples = [(key, your_dict[key]) for key in order_of_keys]
your_dict = OrderedDict(list_of_tuples)

11

Çoğu zaman ASC vb.

İşte önerilen çözüm:

import collections
ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship


new_dict = collections.OrderedDict()
new_dict["NAME"]=ship["NAME"]
new_dict["HP"]=ship["HP"]
new_dict["BLASTERS"]=ship["BLASTERS"]
new_dict["THRUSTERS"]=ship["THRUSTERS"]
new_dict["PRICE"]=ship["PRICE"]


print new_dict

Bu çıktı:

OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])
OrderedDict([('NAME', 'Albatross'), ('HP', 50), ('BLASTERS', 13), ('THRUSTERS', 18), ('PRICE', 250)])

Not : Yeni sıralanmış sözlükler, girişler silindiğinde sıralama düzenini korur. Ancak yeni anahtarlar eklendiğinde, anahtarlar sonuna eklenir ve sıralama korunmaz. ( Resmi doküman )


2

Dict.items () kullanın; aşağıdaki kadar basit olabilir:

ship = collections.OrderedDict(ship.items())
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.