This is my solution to CS50 pset6 DNA problem in python. It works fine on small database but gives this traceback and error:

File "E:\CS50x\pset6-dna\dna.py", line 35, in main
    STR_match[STR[i]] = longest_match(sequence,STR[i])
Index error: List Index Out of range

I have tried print on various variables but can't figure out the problem.

import csv
import sys

def main():

    # TODO: Check for command-line usage
    if len(sys.argv) != 3:
        print("Usage: python dna.py database.csv sequence.txt")

    # TODO: Read database file into a variable
    dna_database =[]
    with open(sys.argv[1], "r") as dna_data_file:
        reader = csv.DictReader(dna_data_file)
        for row in reader:

    # TODO: Read DNA sequence file into a variable
    with open(sys.argv[2], "r") as load_sequence:
        sequence = load_sequence.read()

    # TODO: Find longest match of each STR in DNA sequence
    STR = list(dna_database[0].keys())[1:]
    STR_match ={}
    for i in range(len(dna_database)):
        # print(dna_database)
        STR_match[STR[i]] = longest_match(sequence,STR[i])
        # print(len(STR) + 1)
        # print(len(dna_database[0].keys()))
        # print(STR_match[STR[i]])
        # print(longest_match(sequence,STR[i]))

    # TODO: Check database for matching profiles
    for i in range(len(dna_database)):
        matches = 0
        for j in range(len(STR)):
            if int(STR_match[STR[j]]) == int(dna_database[i][STR[j]]):
                matches += 1
                if matches == len(STR):

    print("No Match")


def longest_match(sequence, subsequence):
    """Returns length of longest run of subsequence in sequence."""

    # Initialize variables
    longest_run = 0
    subsequence_length = len(subsequence)
    sequence_length = len(sequence)

    # Check each character in sequence for most consecutive runs of subsequence
    for i in range(sequence_length):

        # Initialize count of consecutive runs
        count = 0

        # Check for a subsequence match in a "substring" (a subset of characters) within sequence
        # If a match, move substring to next potential match in sequence
        # Continue moving substring and checking for matches until out of consecutive matches
        while True:

            # Adjust substring start and end
            start = i + count * subsequence_length
            end = start + subsequence_length

            # If there is a match in the substring
            if sequence[start:end] == subsequence:
                count += 1

            # If there is no match in the substring

        # Update most consecutive matches found
        longest_run = max(longest_run, count)

    # After checking for runs at each character in seqeuence, return longest run found
    return longest_run


1 Answer 1


You have an error in this for loop:

for i in range(len(dna_database)):
    STR_match[STR[i]] = longest_match(sequence,STR[i]) 

You are looping on the length of List dna_database, then using value of i to index into List STR. You got lucky with the small databases because they are the same length. The error appears with the large databases (because the 2 lists have different lengths).

The fix is pretty obvious, so I'm going to let you figure it out....

Note, you usually don't need to loop on the index values from range(len(object)). Simply loop on items in the object. That is a much more Pythonic method (and easier to read too!). Example below.
Instead of:

for i in range(len(dna_database)):
    matches = 0
    for j in range(len(STR)):
        if int(STR_match[STR[j]]) == int(dna_database[i][STR[j]]):


for person in dna_database:
        matches = 0
        for sub_str in STR:
            if STR_match[sub_str] == int(person[sub_str]):

Also, the STR_match[sub_str] value is already an int - no need to convert for the equality test.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .