0

I have seen this question as a duplicate (seems all my questions have been duplicates so far)

My code

#UAA + UAG + UGA = STOP
n = 3

xdict = {
    "Phenylalanine": ["UUU", "UUC"],
    "Leucine": ["UUA", "CUU", "CUC", "CUA", "CUG", "UUG"],
    "Isoleucine": ["AUU", "AUC", "AUA"],
    "Methionine": "AUG",
    "Valine": ["GUU", "GUC", "GUA", "GUG"],
    "Serine": ["UCU", "UCC", "UCA", "UCG"],
    "Proline": ["CCU", "CCC", "CCA", "CCG"],
    "Threonine": ["ACU", "ACC", "ACA", "ACG"],
    "Alanine": ["GCU", "GCC", "GCA", "GCG"],
    "Tyrosine": ["UAU", "UAC"],
    "Histidine": ["CAU", "CAC"],
    "Glutamine": ["CAA", "CAG"],
    "Asparagine": ["AAU", "AAC"],
    "Lysine": ["AAA", "AAG"],
    "Asparatic Acid": ["GAU", "GAC"],
    "Glutamic Acid": ["GAA", "GAG"],
    "Cysteine": ["UGU", "UGC"],
    "Trytophan": "UGG",
    "Arginine": ["CGU", "CGC", "CGA", "CGG", "AGG", "AGA"],
    "Serine": ["AGU", "AGC"],
    "Glycine": ["GGU", "GGC", "GGA", "GGG"]
}

lookup_dict = {k: key for key, values in xdict.items() for k in values}
a = input("Enter your DNA sequence: ")
a = a.upper()
print("Your DNA sequence is", a)
str(a)
RNA = a.replace("C", "G")
RNA = a.replace("A", "U")
RNA = a.replace("T", "A")
print("Your RNA strand is", RNA)

b = len(a)

if b % 3 == 0:
  for k in [a[i:i + n] for i in range(0, len(a), n)]:
    if k in xdict.values(): #checking from other question
      print(lookup_dict[k], end=" ")
    elif k not in xdict.values(): #checking from other question
      print("I hate u")

elif b % 3 != 0:
  print("Try again.")

I have tried the answer from this link and it doesn't work for me. How do I detect if a value is in a dictionary in python?

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
GuyOverThere
  • 89
  • 2
  • 8
  • @cricket_007 I will edit so that the checking is clear. – GuyOverThere Dec 13 '19 at 02:39
  • Note that your handling of single values is going to require extra code. You could just put them in a list of 1 to be consistent. Note also that iterating over the string gives you individual characters -- probably not intended. (also fixed by putting it in a list of 1) – Kenny Ostrom Dec 13 '19 at 02:43
  • 1
    You might also have a problem if the same sequence happens to appear somewhere inside two different lists. The lookup dict can only remember one of them, unless it also has lists for values. – Kenny Ostrom Dec 13 '19 at 02:51
  • 2
    It would help if you do not request input. Instead say exactly what value you're looking for, so we can see specifically why it's not being found. – Kenny Ostrom Dec 13 '19 at 02:53
  • Where is this data coming from? It certainly isn't ideal. – AMC Dec 13 '19 at 03:40

2 Answers2

2

You're checking if a string is in a list of lists plus a few strings, so it would return false unless you try to search for those lone strings .

You'd either have to lookup the key, then check if your string is in that key's list value, or loop over all values (which you're already doing) instead like so, then check if it's in the list of the dictionary value

if b % 3 == 0:
  for _, values in xdict.items():
    for k in (a[i:i + n] for i in range(0, len(a), n)):
      if k in values:
        print(lookup_dict[k], end=" ")
      else
        print("I hate u")
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • The key of the lookup dict is created after iterating over the original value's multiple values. (although that goes wrong on the single strings) – Kenny Ostrom Dec 13 '19 at 02:46
  • @cricket_007 When I print this out it repeats "I hate u" for a while and then my first part of answer then the next part and so on until it comes out right... how do I fix this? – GuyOverThere Dec 13 '19 at 02:48
  • I'm not sure I understand the point of the lookup dict, but my answer is more focused on the first dict – OneCricketeer Dec 13 '19 at 02:48
  • The purpose of the lookup dict is because they want to search the values. You can't do that on a dict, which is designed to quickly find things by the key. – Kenny Ostrom Dec 13 '19 at 02:49
  • @cricket_007 The lookup dict definition is to find the values in the dictionary. It doesn't do error handling, however. – GuyOverThere Dec 13 '19 at 02:49
  • @cricket_007 Now it comes up like this: ```Glycine I hate u Glycine I hate u Glycine I hate u``` – GuyOverThere Dec 13 '19 at 02:51
  • @Guy you could add a break in the loop, but it currently attempts to scan all items, so you would see duplicates, yes – OneCricketeer Dec 13 '19 at 02:55
  • What's the input? – Kenny Ostrom Dec 13 '19 at 03:03
  • @cricket_007 I mean that is the "I hate u" part keeps coming up after the word – GuyOverThere Dec 13 '19 at 10:50
  • @Guy and like I explained, you could add a break statement to exit the loop before that gets printed, or you can edit the logic however you want... The point of the answer is to fix the in statement, not solve the overall problem – OneCricketeer Dec 13 '19 at 14:05
0

You can do this with pandas, it's a good approach for searching like this:

import pandas as pd
df =  pd.DataFrame(list(xdict.items()))


def lookupKey(df, key):
  return df[df[1].apply(lambda x: True if key in x else x) == True][0].reset_index()[0][0]

lookupKey(df, 'CGU')
# 'Arginine'
oppressionslayer
  • 6,942
  • 2
  • 7
  • 24
  • `[df[1].apply(lambda x: True if key in x else x) == True]` --> `[df[1].apply(lambda x: True if key in x else x) is True]` --> `[df[1].apply(lambda x: True if key in x else x)]` Also I can't manage to build a DataFrame like that, I get `ValueError: If using all scalar values, you must pass an index`. – AMC Dec 14 '19 at 01:00