As a part of an internal project, I have to parse through a dns zone file records. The file looks roughly like this.

```
    $ORIGIN 0001.test.domain.com.
    test-qa     CNAME   test-qa.0001.test.domain.com.
    $ORIGIN test-qa.domain.com.
    unit-test01     A   192.168.0.2
    $TTL 60 ; 1 minute
    integration-test    A   192.168.0.102
    $ORIGIN dev.domain.com.
    web     A       192.168.10.10
    $TTL 300; 5 minutes
    api     A   192.168.10.13

```

Default ttl is 3600, that is, for the above data, 

```
test-qa     CNAME   test-qa.0001.test.domain.com. 

```

has a ttl of 3600 because it doesn't have a $TTL mentioned anywhere. However, 

```
unit-test01     A   192.168.0.2 

```

has a ttl of 3600 and 

```
integration-test    A   192.168.0.102

```

has a ttl of 60 secs.

I am trying to create a datastructure out of this data above, and I guess a dictionary would be the best possible way to traverse through this data.

What I did:

```
origin = re.compile("^\$ORIGIN.*")
ttl = re.compile("^$TTL.*")
default_ttl = "$TTL 3600"
data_dict = {}
primary_key = None
value = None
for line in data_zones:
    if origin.search(line):
            line = line.replace("$ORIGIN ", "")
            primary_key = line
    elif ttl.search(line):
            default_ttl = line
    else:
            value = line
    data_dict[primary_key] = [default_ttl]
    data_dict[primary_key][default_ttl] = value

```

I want to convert it into a dictionary, but I get the error

```
TypeError: list indices must be integers, not str

```

My sample data structure need to look something like

```
0001.test.domain.com.: #This would be the first level Key
    ttl:3600: #This would be the second level key
        test-qa     CNAME   test-qa.0001.test.domain.com. #Value

test-qa.domain.com.: #This would be the first level Key
    ttl:3600: #This would be the second level key
        unit-test01     A   192.168.0.2 #value
    ttl:60: #This would be the second level key
        integration-test     A  192.168.0.102 #value

```

What am I doing wrong here?
['https://Stackoverflow.com/questions/27767713', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3354434/']
Before we look at the detail of the problem, there's a few things that could be cleaned up in this code that would make the error easier to find. Following code quality guidelines make code easier to maintain and understand, in particular - variable names should always be descriptive and tell the reader what the variable is going to represent. A bad variable name doesn't tell the reader anything about what it contains, and a terrible variable name will tell the reader that the variable contains something it doesn't. 

Here we have a variable here called default\_ttl. A casual reader might well make an assumption that this variable is always going to contain the default ttl, but in the code sample above, the variable is overwritten as soon as a ttl is specified in the source data.

```
default_ttl = line

```

It might be a lot clearer to specify a default TTL at the top of the code, and then use assign this value to a variable called, say : current\_ttl, whenever a new origin is encountered.

So at the top of the file we would have : 

```
DEFAULT_TTL = '$TTL 3600'

```

And every time a new origin is encountered, the current ttl would be reset to the default.

```
if origin.search(line):
            line = line.replace("$ORIGIN ", "")
            current_ttl = DEFAULT_TTL

```

When a specific TTL is encountered in the source data, the appropriate value can then be assigned to current TTL: 

```
elif ttl.search(line):
        current_ttl = line

```

Once this change is made, the bottom two lines of code would become: 

```
data_dict[primary_key] = [current_ttl]
data_dict[primary_key][current_ttl] = value

```

The cause of the error is that you are creating a list containing exactly one entry - the current\_ttl, and creating an entry in the data\_dict dictionary containing that list. 

On the next line, you get the list back out of the dictionary, and try and access it using the index current\_ttl. current\_ttl contains a string, and a list can only be accessed using an integer. The interpreter gives you an error message that sums this up succinctly! 

Without major modifications to your code, the quickest clean up is to use a defaultdict for the top level data\_dict:

```
from collections import defaultdict
data_dict = defaultdict(dict) 

```

So now, whenever we try to refer to a key in data\_dict that does not already exist, a new empty dictionary will be created for us by the defaultdict object and inserted to data\_dict at that key we tried to access.

The line 

```
data_dict[primary_key] = [default_ttl]

```

Is now redundant and unnecessary, it can be removed from the code altogether, leaving : 

```
from collections import defaultdict
origin = re.compile("^\$ORIGIN.*")
ttl = re.compile("^$TTL.*")
DEFAULT_TTL = "$TTL 3600"
data_dict = defaultdict(dict)
primary_key = None
value = None
for line in data_zones.split('\n'): #Split by line not character
    if origin.search(line):
                line = line.replace("$ORIGIN ", "")
                current_ttl = DEFAULT_TTL
                primary_key = line
    elif ttl.search(line):
            current_ttl = line
    else:
            value = line
    data_dict[primary_key][current_ttl] = value

```
The line of error is 

```
data_dict[primary_key][default_ttl] = value

```

Because `data_dict[primary_key]` is a list and not a dictionary object. You can fix this by doing 

```
data_dict[primary_key] = {default_ttl: value}

```