Bir OrderedDict'in yapıcısını kullanarak ilk verilerin sırasını koruyacak şekilde başlatmanın doğru yolu?


124

Sıralı bir sözlüğü (OD) ilk verilerin sırasını korumak için başlatmanın doğru yolu nedir?

from collections import OrderedDict

# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1}) 

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])

# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])

Soru:

  • Bir olacak OrderedDictküpe veya listeleri ya da vb listelerinin listesinin başlığın bir dizilerini listesi ya da başlığın sırasını korumak başlatma (2 & 3, örneğin yukarıda) anda geçmiş?

  • OrderedDictBir emrin gerçekten devam edip etmediğini doğrulamaya nasıl devam edilir? Bir yana dicttahmin edilemez bir düzeni vardır ne benim test vektörler Neyse ki bir dict öngörülemeyen siparişle aynı başlangıç siparişi varsa? Örneğin, d = OrderedDict({'b':2, 'a':1})yazmak yerine d = OrderedDict({'a':1, 'b':2})yazarsam, yanlış bir şekilde siparişin korunduğu sonucuna varabilirim. Bu durumda, dicta'nın alfabetik olarak sıralandığını öğrendim , ancak bu her zaman doğru olmayabilir. Bir veri yapısının düzeni koruyup korumadığını doğrulamak için bir karşı örnek kullanmanın güvenilir yolu nedir? Test vektörlerini biri bozulana kadar tekrar tekrar denemek yerine?

PS Ben sadece burada bırakacağız referans "Python'un işlev çağrısı anlambilim geçiş nedeniyle OrderedDict yapıcı ve güncelleme () yöntemini hem anahtar kelime argümanlar kabul eder, ancak bunların sırası kaybolur anahtar kelime argümanlar düzenli sırasız sözlük kullanılarak":

PPS: Umarım gelecekte OrderedDict kwargs sırasını da koruyacaktır (örnek 1): http://bugs.python.org/issue16991


10
Bir OrderedDict'in (boş olmayan) bir dikte ile başlatılmasının yapılması yanlış bir şey olduğu belirsiz bir şekilde ironiktir ... muhtemelen bu, muhtemelen kullanıcının niyetini ihlal ettiği için bir Uyarı ile sonuçlanmalıdır.
smci

3
Python3.6'dan sonra OrderDict(b=2, a=1)da uygun bir yoldur. Bakınız PEP 468 .
IvanaGyro

Yanıtlar:


90

OrderedDict, erişebildiği tüm siparişleri koruyacaktır. Sıralı veriyi başlatmak için ona geçirmenin tek yolu, son iki örneğinizde olduğu gibi anahtar-değer çiftlerinin bir listesini (veya daha genel olarak, bir yinelenebilir) geçirmektir. Bağlandığınız dokümantasyonun söylediği gibi, OrderedDict anahtar kelime argümanlarını veya bir dikt argümanını ilettiğinizde herhangi bir sıraya erişemez, çünkü OrderedDict kurucusu görmeden önce oradaki herhangi bir sıra kaldırılır.

Son örneğinizde bir liste anlama kullanmanın hiçbir şeyi değiştirmediğini unutmayın. Arasında hiçbir fark yok OrderedDict([(i,i) for i in l])ve OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]). Listenin anlaşılması değerlendirilir ve liste oluşturulur ve içeri aktarılır; OrderedDict nasıl oluşturulduğu hakkında hiçbir şey bilmiyor.


74
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

Evet, işe yarayacak. Tanım olarak, bir liste her zaman temsil edildiği şekilde sıralanır. Bu liste-kavrama için de geçerlidir, üretilen liste verinin sağlandığı yolla aynıdır (yani bir listeden kaynak belirleyici olacaktır, a'dan kaynaklanacak setveya dictçok olmayacaktır).

OrderedDictBir emrin gerçekten devam edip etmediğini doğrulamaya nasıl devam edilir? Bir diktenin öngörülemeyen bir sırası olduğu için, ya şans eseri benim test vektörlerim bir diktenin öngörülemeyen sırası ile aynı başlangıç ​​sırasına sahipse? Örneğin, d = OrderedDict({'b':2, 'a':1})yazmak yerine d = OrderedDict({'a':1, 'b':2})yazarsam, yanlış bir şekilde siparişin korunduğu sonucuna varabilirim. Bu durumda, dicta'nın alfabetik sırayla olduğunu öğrendim , ancak bu her zaman doğru olmayabilir. başka bir deyişle, bir veri yapısının sırayı koruyup korumadığını doğrulamak için bir sayaç örneği kullanmanın güvenilir yolu nedir?

Referans için 2 parçalı kaynak listenizi saklayın ve birim testleri yaparken bunu test durumlarınız için test verileriniz olarak kullanın. Bunları tekrarlayın ve sıranın korunmasını sağlayın.


Siparişin doğrulanması hakkında: 2'li grubumun öngörülemezse dikte sırasını bozacağından nasıl emin olabilirim? Bu, herhangi bir veri yapısı hakkında genel bir sorudur, belki de onu bu sorudan ayırmalıyım.
tıklayın

1
Doğası gereği deterministik olmayan bir şeyi deterministik olarak kıramazsınız.
metatoaster

1
Peki bu tür şeyleri test etmek için doğru yaklaşım nedir? Süresiz olarak denemeye devam mı ediyorsun? Sıra programcılar için tahmin edilemez, ancak bir karma harita olduğu için 'bazı' algoritmaları izliyor ve doğru bir test buna karşı koymaya çalışmalı mı?
tıklayın

2
Bakın __hash__. Özellikle strtür hakkında.
metatoaster

Tanım olarak, bir liste her zaman temsil edildiği şekilde sıralanır. Bu benim için önemli bir ifadeydi. Ben sadece benim temel için 2 tüp listeleriniz kullanmaya karar OrderedDictBir üzere bir liste dönüştürme yükü yok ki OrderedDict. Bir sözlük yerine bir liste gibi öğelerin üzerinden geçiyorum.
Bobort
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.