0

I have a nested dictionary in my project:

>>> dict = {
    "content": """<p>It is common for content in Arabic, Hebrew, and other languages that use right-to-left scripts to include numerals or include text from  other scripts. Both of these typically flow  left-to-right within the overall right-to-left  context. </p>""", 
    "name": "directory", 
    "decendent": [
         {
            "content": """<p>This article tells you how to write HTML where text with different writing directions is mixed <em>within a paragraph or other HTML block</em> (ie. <dfn id="term_inline">inline or phrasal</dfn> content). (A companion article <a href="/International/questions/qa-html-dir"><cite>Structural markup and right-to-left text in HTML</cite></a> tells you how to use HTML markup for  elements such as <code class="kw">html</code>, and structural markup such as <code class="kw">p</code> or <code class="kw">div</code> and forms.)</p>""", 
            "name": "subdirectory", 
            "decendent": None
        }, 
        {
            "content": """It tells you how to use HTML markup for  elements such as <code class="kw">html</code>, and structural markup such as <code class="kw">p</code> or <code class="kw">div</code> and forms.)""", 
            "name": "subdirectory_two", 
            "decendent": [
                {
                    "content": "Name 4", 
                    "name": "subsubdirectory", 
                    "decendent": None
                }
            ]
        }
    ]
}

and a function which generates it:

def getname(dirpath):
    onlyfile = [entry for entry in os.listdir(dirpath) if os.path.isfile(os.path.join(dirpath, entry)) and entry.endswith(".txt")][0]
    onlyfilename = os.path.join(dirpath, onlyfile)

    decendent = []
    for entry in os.listdir(dirpath):
        entrypath = os.path.join(dirpath, entry)
        if os.path.isfile(entrypath):
            continue
        decendent.append(getname(entrypath))

    if len(decendent) == 0:
        decendent = None

    return {'name': onlyfilename.split("/")[-2],
            'path': onlyfilename.rsplit("/", 1)[-2] + "/index.html",
            'leaf': readFile(onlyfilename),
            'decendent': decendent}

The problem is that it returns an unordered set of dictionaries as descendents:

enter image description here

How to sort them in my case when they're nested?

Павел Иванов
  • 1,863
  • 5
  • 28
  • 51
  • 2
    You have an *ordered list* of dictionaries (not an unordered `set`, something entirely different). Lists can be sorted, so just sort the list. – Martijn Pieters May 13 '15 at 09:51

1 Answers1

3

Your descendent value is just a list. Lists can be sorted, no matter where they are referenced. That it is inside a dictionary doesn't matter here.

Your descendent list order is set by whatever order os.listdir() returns. You can sort that, or you can simply sort the descendent object itself. Sort by using a natural sort for example, or use any other criteria for your sorting.

Using the natural_sort() function from Mark Byer's answer on the os.listdir() result, for example:

for entry in natural_sort(os.listdir(dirpath)):

would list your directory entries in a sorted order for you to insert into the descendant list.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343