1

In the following list data:

attri_values = ['gene_id "scaffold_200002.1"', 'gene_version "1"', 'transcript_id "scaffold_200002.1"', 'transcript_version "1"', 'exon_number "2"', 'gene_source "jgi"', 'gene_biotype "protein_coding"', 'transcript_source "jgi"', 'transcript_biotype "protein_coding"', 'exon_id "scaffold_200002.1.exon2"', 'exon_version "1"']

say I want to apply a conditional expression:

gene_id = [x for x in attri_values if 'gene_id' in x]

# But, when there is not list values with 'gene_id' I would like to return NA (string type) but not an empty list, but I am being unsuccessful

gene_name = [x if 'gene_name' in x else 'NA' for x in attri_values]

print(gene_name) #gives me
['NA', 'NA', 'NA', 'NA', 'NA', 'NA', 'NA', 'NA', 'NA', 'NA', 'NA']

# I only want one 'NA' in string format.

I tried to write else conditions at different points. I also tried several examples from stackE but no success.

if else in a list comprehension

if/else in Python's list comprehension?

Thanks,

Community
  • 1
  • 1
everestial007
  • 6,665
  • 7
  • 32
  • 72
  • What error did you get when you tried using `else`? – Pedro Castilho Apr 17 '17 at 20:04
  • Can you not just convert it to a `set`? Something like `gene_name = list(set([x if 'gene_name' in x else 'NA' for x in attri_values]))` – roganjosh Apr 17 '17 at 20:04
  • I am not getting error so far with what I tried, but I am also not getting an exact thing I want., I also tried lambda. I can run a for loop work this problem out but want to learn a very nice and clean method do solve this problem. I tried several examples from old post, no success so far. – everestial007 Apr 17 '17 at 20:06
  • @roganjosh: your solution works (since it merges same values to one single values), but I think there might be another issue coming up if NA is to reported only one if none match is found, and for the match found to be reported as it is. But, still a good solution. – everestial007 Apr 17 '17 at 20:10
  • It looks like the second set is checking for "gene_name". The data provided does not contain "gene_name" anywhere in it- the program is doing exactly what you're asking- foreach `x` in list, give me `x` or `"NA"`. Your goal would be accomplished better by doing the original comprehension, and checking if the list is empty. – Delioth Apr 17 '17 at 20:10

1 Answers1

3

You should use an or statement in your variable assignment.

gene_id = [x for x in attri_values if 'gene_id' in x] or ['NA']

This way, if your initial list comprehension returns an empty list, you move on to the second half of the or and assign the list ['NA'] to the variable gene_id.

wpercy
  • 9,636
  • 4
  • 33
  • 45
  • 1
    Swap the example to "gene_name" and I think this is the correct answer. The point of "gene_name", I think, was deliberate to get zero matches. – roganjosh Apr 17 '17 at 20:12
  • 1
    Well, yeah, but I figured that OP wanted to get a list of gene_id's and if there weren't any then OP wanted to return the single element list. The gene_name statement was just a contrived example. Regardless, the method itself is correct and can be extended to any use-case – wpercy Apr 17 '17 at 20:14
  • Fair enough, the other answer misinterpreted. Definitely cleaner than my `set` approach in comments :) – roganjosh Apr 17 '17 at 20:15
  • yes, @roganjosh. thats what I wanted. I was writing code for one values which matched and one for the value that didn't had any match. I think it led to confusions. – everestial007 Apr 17 '17 at 20:15