tags:

views:

175

answers:

4

Here's what I have, but it seems kind of redundant. Maybe someone more experienced in Python knows of a way to clean this up? Should be pretty self explanatory what it does.

def complementary_strand(self, strand):
        ''' Takes a DNA strand string and finds its opposite base pair match. '''
        strand = strand.upper()
        newstrand = ""
        for i in range(0, len(strand)):
            if strand[i] == "T":
                newstrand += "A"

            if strand[i] == "A":
                newstrand += "T"

            if strand[i] == "G":
                newstrand += "C"

            if strand[i] == "C":
                newstrand += "G"

        return newstrand
+6  A: 

Even better would be to craft a generator, instead:

TRANS = { "T": "A", "A": "T", "G": "C", "C": "G" }

def complementary_strand(self, strand):
    for base in strand.upper():
        yield TRANS[base]

Then you can use it any way you want, and an iterator is more efficient:

for base in strand.complementary_strand():
    # Do something
Jed Smith
I was going to post something very similar to this, except that I would define the `trans` dict outside that function, because that information is bound to be needed elsewhere and it would be good not to repeat it.
Ben James
It was implied, but I made it definite.
Jed Smith
+3  A: 

Something like

def complementary_strand(self, strand):
    return strand.upper().translate(maketrans("TAGC", "ATCG"))
lhahne
+10  A: 

Probably the most efficient way to do it, if the string is long enough:

import string

def complementary_strand(self, strand):
    return strand.translate(string.maketrans('TAGCtagc', 'ATCGATCG'))

This is making use of the translate and maketrans methods. You can also move the translate table creation outside the function:

import string
def __init__(self, ...):
    self.trans = string.maketrans('TAGCtagc', 'ATCGATCG')

def complementary_strand(self, strand):
    return strand.translate(self.trans)
Nadia Alramli
+1 -- I was looking for `string.maketrans`, since `strand.translate` has that interesting 256-character restriction.
Jed Smith
+1 -- translate is fast as greased lightning, and you're using it just right (esp. in the second, class-based version).
Alex Martelli
@Alex: You aren't kidding, that's a lot faster than I expected.
Jed Smith
+2  A: 
def __init__(self, *args):
    # ... original __init__ method, and:
    self.trans = { "T": "A", "A": "T", "G": "C", "C": "G" }

def complementary_strand(self, strand):
    '''Takes a DNA strand string and returns its opposite base pair match.'''
    return ''.join([self.trans[base] for base in strand.upper()])
Michael