Search code examples
pythondictionarydictionary-comprehension

How to make a nested dictionary from a text file in python?


I have a text file that is structured like so:

SOURCE: RCM
DESTINATIONS BEGIN
JCK SF3
DESTINATIONS END
SOURCE: TRO
DESTINATIONS BEGIN
GFN SF3
SYD SF3 DH4
DESTINATIONS END

I am trying to create a nested dictionary where the resulting dictionary would look like:

handout_routes = {
'RCM': {'JCK': ['SF3']},
'TRO': {'GFN': ['SF3'], 'SYD': ['SF3', 'DH4']}
}

Now this is just a sample of the data but when reading the data we can assume the following: The very first line begins with SOURCE: followed by a three letter IATA airport code. The line after every line that begins with SOURCE: is DESTINATIONS BEGIN. There are one or more lines between DESTINATIONS BEGIN and DESTINATIONS END. After every line with DESTINATIONS BEGIN there is a corresponding line with DESTINATIONS END. The lines between DESTINATIONS BEGIN and DESTINATIONS END start with a three-letter IATA airport code, which is followed by one or more three-character alphaneumeric plane codes. Each code is separated by a space. The lines after DESTINATIONS END will begin with SOURCE:, or you will have reached the end of the file.

So far I've tried

with open ("file_path", encoding='utf-8') as text_data:
    answer = {}
    for line in text_data:
        line = line.split()
        if not line:  # empty line?
            continue
        answer[line[0]] = line[1:]
    print(answer)

But it returns the data like this:

{'SOURCE:': ['WYA'], 'DESTINATIONS': ['END'], 'KZN': ['146'], 'DYU': ['320']}

I think it's how I structured the code to read the file. Any help will be appreciated. It's possible my code is way too simple for what needs to be done with the file. Thank you.


Solution

  • Here's a program I wrote that works quite well:

    def unpack(file):
      contents:dict = {}
      source:str
      
      for line in file.split('\n'):
    
        if line[:12] == 'DESTINATIONS':
          pass
        #these lines don't affect the program so we ignore them
    
        elif not line:
          pass
        #empty line so we ignore it
        
        elif line[:6] == 'SOURCE':
          source = line.rpartition(' ')[-1]
          if source not in contents:
            contents[source] = {}
          
        else:
          idx, *data = line.split(' ')
          contents[source][idx] = list(data)
    
      return contents
          
    
    with open('file.txt') as file:
      handout_routes = unpack(file.read())
      print(handout_routes)