2014-03-28 110 views
8

origOrderedDict其中包含正常字符串:字符串鍵值對,但有時該值可能是另一個,嵌套OrderedDict按鍵遞歸排序嵌套的OrderedDict

我想按鍵排序orig,按字母順序排列(遞增),並按遞歸執行

規則:

  • 假設關鍵字符串是不可預知的
  • 假設築巢可能發生無限,例如級別1-50都具有字符串,OrderedDicts等作爲值。

需要與sorted算法的幫助:

import string 
from random import choice 


orig = OrderedDict((
    ('a', choice(string.digits)), 
    ('b', choice(string.digits)), 
    ('c', choice(string.digits)), 
    ('special', OrderedDict((
     ('a', choice(string.digits)), 
     ('b', choice(string.digits)), 
     ('c', choice(string.digits)), 
    ))) 
)) 

sorted_copy = OrderedDict(sorted(orig.iteritems(), ...)) 

self.assertEqual(orig, sorted_copy) 
+0

它只是一個單一的深度?或者與'special'相對應的'OrderedDict'可以在裏面有另一個'OrderedDict'? –

+0

@SukritKalra我在這個問題中增加了一個'Rules'部分,希望這個問題可以在不需要OrderedDict結構的專門知識的情況下重新使用。 – tester

+1

@StevenRumbalski需要它來安全地創建包含大量不同嵌套數據類型的字典的校驗和。儘管字典的內容在技術上沒有改變,但像字典鍵順序這樣的小事情正在改變校驗和。在使用'hashlib.md5(str(my_dict).hexdigest()'快速計算字典的散列值之前對這些鍵進行排序,這使我能夠安全地比較將來的版本(真正的原因是MongoDB並不保證每個對象的順序:http:// docs.mongodb.org/manual/core/document/#document-limitations)TLDR:...長篇小說 – tester

回答

12

類似:

def sortOD(od): 
    res = OrderedDict() 
    for k, v in sorted(od.items()): 
     if isinstance(v, dict): 
      res[k] = sortOD(v) 
     else: 
      res[k] = v 
    return res 
4

非常相似@ acushner的解決方案,但基於類:

from collections import OrderedDict 


class SortedDict(OrderedDict): 

    def __init__(self, **kwargs): 
     super(SortedDict, self).__init__() 

     for key, value in sorted(kwargs.items()): 
      if isinstance(value, dict): 
       self[key] = SortedDict(**value) 
      else: 
       self[key] = value 

用法:

sorted_dict = SortedDict(**unsorted_dict) 
+0

不錯。額外的功勞,如果在插入額外的值時或者在調用'my_sorted_dict.sort()時仍然保持排序的話 – Eldamir

+0

This可以通過覆蓋你選擇的迭代器(或所有這些)來實現: def items(self): for key,value in sorted(self.keys()): yield key,value 字典中的項將被讀取而不是插入。 – svvitale

1

@ acushner的解決方案現在可以在python3.6 +中簡化,因爲詞典現在保留了它們的插入順序。

鑑於我們現在可以使用標準的字典,代碼現在看起來像:

def order_dict(dictionary): 
    result = {} 
    for k, v in sorted(dictionary.items()): 
     if isinstance(v, dict): 
      result[k] = order_dict(v) 
     else: 
      result[k] = v 
    return result 

因爲我們可以使用標準的字典,我們也可以使用標準的字典解析,所以代碼歸結爲:

def order_dict(dictionary): 
    return {k: order_dict(v) if isinstance(v, dict) else v 
      for k, v in sorted(dictionary.items())} 

另請參見https://mail.python.org/pipermail/python-dev/2016-September/146327.html瞭解有關python的有序字典實現的詳細信息。此外,這將是一個Python語言特性的聲明3.7:https://mail.python.org/pipermail/python-dev/2017-December/151283.html