Python3: List of strings, where strings having variable letters (not all letters at not all positions)

Viewed 46

first some biological background, so you understand my question. In biology, DNA-sequences can contain motifs, which are recognized by enzymes or proteins. Those motifs are strings, like "GACTGC". Analyses can reveal, whether a position in the motif is "conserved" or not.

Enzymes might recognize "GACTGC" best, but may also recognize "CACTGC" or even "TTCTGC". So, some positions may vary.

I have the following situation: I want to create a list of permutations, with motifs, that could be recognized. In order to do so, I have the info:

Best recognition: GACTGC

Bases, also possible:

GACTGC
A  C G
T    A

which means, at first position, there could alsoe be A or T, at 4th there could be a C etc., but at 2nd position, the A is conserved, nothing else is possible.

I can generate a list with one base varying for each position, by turning the "best-fit" motif into a list of letters and replacing one letter, joining and appending to my list (doing that for each position). So it basically is hard coded. It worked out, since I changed any position, no matter what motif was entered. But now I want to change specific positions to specific letters and store specific permutations only, depending on the motif.

So, I am looking for the shortest/fastest/maybe smartest way, to pass the information of the positions and their valid letters, and how to create the permutations for one and two variable positions.

please note: I will try to post my code in an answer or via an edit, somehow copy-paste and then ctrl+k on the marked code does not work

1 Answers

There might be a way to solve this problem with itertools, but I think it can be done quick enough with a self-made permutation function:

example_bases = [
  "GAT",  # options for first position
  "A",    # options for second position
  "C",    # ...
  "TC",
  "G",
  "CGA"
]

def permutate(bases, results, depth=0, current_result=""):
"""Create permutations of a list of strings

All resulting strings have the length len(bases), and there will be a total
of mult([len(options) for option in bases]) total results, e.g.:
["abc", "de", "fghi"] -> 3 * 2 * 4 -> 24

:param bases: List of possible options for a base
:param results: The object which will contain all valid results
:param depth: Internal counter for current recursive depth 
:param current_result: Internal variable to keep track of progress 
"""
  if depth == len(bases):
    results.append(current_result)
  else:
    for base in bases[depth]:
      permutate(bases, results, depth+1, current_result+base)

example_results = []
permutate(example_bases, example_results)
for sequence in example_results:
  print(sequence)

prints the 18 possible combinations for this particular example:

GACTGC
GACTGG
GACTGA
GACCGC
GACCGG
GACCGA
AACTGC
AACTGG
AACTGA
AACCGC
AACCGG
AACCGA
TACTGC
TACTGG
TACTGA
TACCGC
TACCGG
TACCGA

If recursion is not your thing or you have a question about the code, please feel free to ask.

Related