# Counting adenine and cytosine bases

I've started a little challenge on a website, and the first one was about counting different DNA letters. I've done it, but I found my method very brutal. I have a little experience, and I know that hard-coded information is not good. Any way to improve this code?

chaine = "AAAACCCGGT"

nA = 0
nT = 0
nG = 0
nC = 0

for i in range(len(chaine)):
if chaine[i] == "A":
nA = nA + 1
if chaine[i] == "C":
nC = nC + 1
print nA, nC

• Hi. Welcome to Code Review! It often helps if you can describe the problem that the code is solving. It looks like this is counting the As and the Cs in the string and then printing them. Is that how you'd describe it? Why not the Gs and Ts? – Brythan Feb 15 '15 at 23:49
• The G's and T's too, but the code is redundant, so I didn't print that part of the code. – Chirac Feb 15 '15 at 23:52
• In Code Review, it's best to just copy your exact code unless it is exceptionally long. – Brythan Feb 16 '15 at 0:07

for i in range(len(...)): is almost never the right way to go in Python. Instead, in this case, you should iterate directly over the characters:

for char in chaine:
if char == 'A':
...


Rather than separate names nA, nC, etc., use a dictionary to map each character to its count:

counts = {'A': 0, 'C': 0, ...}


Now you don't need the ifs at all:

for char in chaine:
counts[char] += 1
print counts['A'], counts['C']


In fact, Python already implements collections.Counter, a dictionary subclass that makes this task trivial:

from collections import Counter

counts = Counter(chaine)
print counts['A'], counts['C']


The complete version is

from collections import Counter

chaine = "AAAACCCGGT"

counts = Counter(chaine)

for letter, count in counts.items():
print letter, count


This will print all the counts, not just the two in your code. More details on iterating over associative arrays in Python. You've already seen Jon's answer introducing the Counter.