Instead of checking if the value of an element in the dictionary is integer to find out if it has children or not, what should I do? What can I do?
The problem is that you use different views for sections with children and for sections without children. A section without children should simply be a section with an empty list of children:
sitemap = {'section_one': [0, {}], 'section_two': [1, {'c_sect_2_1': [10, {}], 'c_sect_2_2': [11, {'c_sect_2_2_1': [110, {}], 'c_sect_2_2_2': [111, {}], 'c_sect_2_2_3': [112, {}]}], 'c_sect_2_3': [12, {}], 'c_sect_2_4': [13, {}]}], 'section_three': [2, {}], 'section_four': [3, {}], 'section_five': [4, {}]}
Your code should now be a little easier.
What could be an alternative to all this? (a method of constructing a data structure and / or iteration through it)
You can convert a sitemap into a flat dictionary at the beginning of your program so that it becomes something like
flat_sitemap = { 'section_one': 0, 'section_two': 1, 'section_two/c_sect_2_1': 10, # ... 'section_two/c_sect_2_2/c_sect_2_2_1': 110 # ... }
This way your queries will work in the expected O(1) time due to higher space utilization.
As for handling the original structure differently, you can use recursion. It is often easier for me to recursively formulate an algorithm on a tree structure, but it depends a little on your thinking. Here is an example (I accept the sitemap format, which is shown in my first example):
def map_url(url, sm=[None, sitemap]): if not url: return sm[0] if url[0] not in sm[1]: return False return map_url(url[1:], sm[1][url[0]]) print map_url(['section_two', 'c_sect_2_2', 'c_sect_2_2_3']) # => 112 print map_url(['section_two', 'c_sect_2_2']) # => 10 print map_url(['section_two', 'notexisting']) # => False print map_url([]) # => None
As you can see, this makes the special case explicit when you pass an empty URL. You should definitely think about what should happen in this particular case.
You can even leave the second line of the function. In this case, a KeyError will be KeyError if the URL cannot be matched (which also seems reasonable).