0

I have been practising python and have a small question. I am working with DNA sequences and so I simply wanted to make a small function that just returned the record.ids.

from Bio import AlignIO
my_alignment = Align.IO.read("multipleseqfile.fa","fasta")

def get_id_names(alignment):
    for record in alignment:
        return record.id 

print get_id_names(my_alignment)

I had done a for loop before that prints the names nicely but I wanted to improve my script and make these exercises into functions. However, when I use this function, it only returns the first record id (and there is a list of 30-40). I switched the return record.id to print record.id, and it does print all the names but then I get a None at the end of the output. Not sure what is going on here?

CuriousDude
  • 1,087
  • 1
  • 8
  • 21
  • Change return to yield. return will take the first value and break out. You don't want that. – cs95 Jul 07 '17 at 22:12
  • I tried that but then I don't get a list of the names, just a generator object. If I keep the "print record.id" statement, followed by a "return alignment" (not indented under the print statement) after, it prints all the names and then the alignment records but no None statement. I just want the names to come up after so that I can later extract the sequences. – CuriousDude Jul 07 '17 at 22:17
  • You can't clean up a for loop any more than that one is. If you do what @cᴏʟᴅsᴘᴇᴇᴅ said, you'd still need your main code to loop through the results of that generator, resulting in double work for your program with no readability benefit. Your simple for loop is as good as it gets. If you want your function to print that list, move the print statement into the function (replacing the return) and call the function all by itself. – Alan Leuthard Jul 07 '17 at 22:19
  • If I change the return statement into a print statement, I do get the names but then I get a None at the end. I am wondering why the None also has to show up? I think that will cause problems when I expand (or attempt to) this function. – CuriousDude Jul 07 '17 at 22:21
  • `return record.id` --> `print record.id` and `print get_id_names(my_alignment)` --> `get_id_names(my_alignment)` – cs95 Jul 07 '17 at 22:23
  • @DNAngel because you are still `print` ing the result of your function, but now since you removed the `return` statement, your function returns `None` implicitly. – juanpa.arrivillaga Jul 07 '17 at 22:25
  • That worked! Thank you :) Can you tell me why removing the print in the call statement made a difference? (I practised on datacamp and I always had to print the call statement) – CuriousDude Jul 07 '17 at 22:25
  • Because, when you replaced the `return` with `print` in your function, the function now *implicitely returns `None`*. Functions always return something in Python, and if you don't explictly return something, it automatically returns `None`. I've added a couple more duplicate targets, read those questions and answers and it should become more clear – juanpa.arrivillaga Jul 07 '17 at 22:27
  • In particular, [this](https://stackoverflow.com/questions/17897589/python-why-return-won%C2%B4t-print-out-all-list-elements-in-a-simple-for-loop-and) question is almost exactly the same as yours. – juanpa.arrivillaga Jul 07 '17 at 22:29
  • Thank you again for the help! :) – CuriousDude Jul 07 '17 at 22:32

0 Answers0