Building a dictionary with lists using recursion - python-3.x

I was trying to build a dictionary with recursion for a school project. Right now I think I have the general structure figured out, but I can't figure out how to get the return statement to concatenate pieces of the dictionary together.
I realize this would probably be easier by constructing an empty dictionary then adding to it, but I wanted to see if there were any tricks I could use.
The output I was looking for is:
print(recur_join([1,2,3], ['a', 'b', 'c']))
>>> {1: 'a', 2 : 'b', 3 : 'c'}
I have tried .update() and something of the form dict(basket_one, **basket_two) from another answer. I may have used them wrong. I am using python 3.
Here is my code as of now:
def recur_join(list1, list2):
if len(list1) == len(list2):
if len(list1) == 1:
return {list1[0]: list2[0]}
elif len(list1) > 1:
# dict(basket_one, **basket_two)
#return dict({list1[0]: list2[0]}, **recur_join(list1[1:],
list2[1:]))
return {list1[0]: list2[0]}.update(recur_join(list1[1:], list2[1:]))
else:
print('lists do not match in size')
return 0
Any help would be appreciated, sorry if this was answered before.
Thanks!

I suggest you don't use recursion and use dict comprehensions instead:
def recur_join(list1, list2):
if len(list1) != len(list2):
print('lists do not match in size')
return
else: return {list1[i]:list2[i] for i in range(len(list1))}
For the recursive route (warning: very ugly):
def recur_join(list1, list2):
if len(list1) != len(list2):
print('lists do not match in size')
return
elif list1 == [] and list2 == []:
return {}
else:
return dict(list({list1[0]: list2[0]}.items()) + list(recur_join(list1[1:], list2[1:]).items()))

"Cleanish" recursive solution. I would personally use Primusa's dictionary
comprehension solution.
def recur_join(list1, list2):
cur = {}
if len(list1) == len(list2) and len(list1) > 0:
cur = {list1[0]: list2[0]}
if len(list1) > 1:
cur.update(recur_join(list1[1:], list2[1:]))
else:
print('lists do not match in size')
return cur

Related

How does list1 == list2.reverse() gets executed in python?

I am trying to compare two lists(as shown) and I have written a code based on my own logic. According to my logic I have to get output as 'Yes' but I am getting 'No' as output. I think there is something wrong in line3 of my code. According to my logic, in line 3, list2 gets reversed first and then it is compared with list1. With this logic, I have to get output as 'Yes'. Is my logic correct? If not please help me how line3 gets executed.(I am new to python)
list1 = ['a','m','y']
list2 = ['y','m','a']
if list1 == list2.reverse():
print('Yes')
else:
print("No")
Given Output: No;
Expected Output: Yes
list2.reverse() will not return anything i.e. None, but it modifies your list
below is the correct code:
list1 = ['a','m','y']
list2 = ['y','m','a']
list2.reverse()
if list1 == list2:
print('Yes')
else:
print("No")
because list2.reverse() returns 'None' and it change list2to ['a','m','y']. Use this ->
list2 = ['y','m','a']
list2.reverse()
if list1 == list2:
print('Yes')
else:
print("No")
you might code like below:
list1 = ['a','m','y']
list2 = ['y','m','a']
list2.reverse()
if list1 == list2:
print('Yes')
else:
print("No")
>>> Yes
Or like this:
list1 = ['a','m','y']
list2 = ['y','m','a']
if list1 == list(reversed(list2)):
print('Yes')
else:
print("No")

def function to compare two strings

we need to define a function that compares two strings and if they are different we want to know the index. the problem is that no matter what insert we use we always get -1 even when they are not the same.
def mutation_detector(seq1,seq2):
if DNAval(seq1) and DNAval(seq2) == True:
if len(seq1) == len(seq2):
for i in range(0, len(seq1)) and range(0, len(seq2)):
if seq1[i] != seq2[i]:
return(i)
else:
return(-1)
else:
return('Wrong input')
else:
return('Wrong input')
print(mutation_detector('ATCGGGTA','ATCGGCTA'))
Basically you're using and wrong and have some basic Logic errors I think:
and doesn't say "do A and B" but rather"if A is True and B is True"
My attempt at fixing it is as follows:
if DNAval(seq1) and DNAval(seq2):
if len(seq1) == len(seq2):
for (i, (elem1, elem2)) in enumerate(zip(seq1, seq2)):
if elem1 != elem2:
return i
return -1
Your if-else in the loop always returns in the First loop iteration: it takes the first two chars and compares them; are they equal? No -> return -1
If you follow the logic, it begins comparing strings. If the two letters are the same, it goes for the ELSE (because they are not different) and ends the routine after checking only the first letter.
You only want the routine to return -1 if it makes it all the way through the for loop without returning an index number. So,
Change as below:
def test(seq1, seq2):
if len(seq1) == len(seq2):
for i in range(0, len(seq1)):
if seq1[i] != seq2[i]:
return(i)
return(-1)
else:
return('Wrong input')
print( test('Hello1', 'Hello2'))
print('done')
The problem is, that you are returning -1 on the first time you run through the for loop, because the else-clause is immediately entered.
Use the else clause with the for loop itself instead.
For example:
def compare_strings(seq1, seq2):
if len(seq1) == len(seq2):
for i in range(0, len(seq1)):
if seq1[i] != seq2[i]:
return i
else:
return -1
else:
return 'Wrong input'
(mind you, raising a custom exception might be better than returning "Wrong input" here...)
Here's how I would do it
def mutation_detector(seq1, seq2):
if not DNAval(seq1) or not DNAval(seq2) or len(seq1) != len(seq2):
return "Wrong input" # maybe raise ValueError if DNAval fails instead?
for index, (base1, base2) in enumerate(zip(seq1, seq2)):
if base1 != base2:
return index
return -1
Try this,
It will return index when unable to compare otherwise it will compare two character and to print equal again compare it with length of string.
def mutation_detector(seq1,seq2):
count=0
if len(seq1) == len(seq2):
for i in range(0, len(seq1)) and range(0, len(seq2)):
if seq1[i] != seq2[i]:
return i
else:
count=count+1
if count==len(seq1):
return 'Equal'
print(mutation_detector('ATCGGCTA','ATCGGCTA'))
def comp_string(string1,string2):
if len(string1)!=len(string2):
return "length not equal"
else:
for i in range(len(string1)):
if string1[i] != string2[i]:
return i
return "equal"

List index out of range? If statement

I have a truly puzzling issue
Im using some nested if statements to produce a list, using variables from lists
if List1[0] or List2[0] or List3[0] or List4[0] or List5[0] == 'Something':
Now my assumption is that it would check for a value in either spot to be my specific word, then continue to the next statement if not, however it stops here.
here's a little bit more of the breakdown so you can see my goal here
for i in range(5):
if List1[0] or List2[0] or List3[0] List4[0] or List5[0] == 'Something':
SuperList.append('example1, example2, example3')
if List1[0] == 'Something':
List1.remove('Something')
elif List2[0] == 'Something':
List2.remove('Something')
elif List3[0] == 'Something':
List3.remove('Something')
elif List4[0] == 'Something':
List4.remove('Something')
elif List5[0] == 'Something':
List5.remove('Something')
elif List1[0] or List2[0] or List3[0] or List4[0] or List5[0] == 'SomethingElse':ECT.....
Anyway, i know for certain that all lists 1-5 contain exactly 1 Word, as i had my program print them all too me prior to the long if/nested if function to come
Any help would be greatly appreciated
I believe what the problem here is that you are only comparing List5[0] to 'Something'. You need to compare 'Something' to each value individually. (As a side note, because you are not comparing all of the values, Python expects a boolean value, while your lists hold string values).
To fix your problem you could do this for example:
if List1[0] == 'Something' or List2[0] == 'Something' or List3[0] == 'Something' or List4[0] == 'Something' or List5[0] == 'Something':
# The rest of your code here
Again, you have to compare each value individually so that they can become booleans. That seems to be the only problem with your code. I hope this cleared it up for you.

Replace method and for loops

Im trying to do reverse transcription of a DNA sequence by reversing a string then find its corresponding pair ( if an 'A' appears then switch with a 'T') and return a new string that is 'reverse transcribed'. The loop seems to work only partially and not go through to the elif statements. I've tried two ways and have the same problem:
def structures(seq):
revlist = seq[::-1]
for item in revlist:
if item == 'A':
return revlist.replace('A','T',1000)
elif item == 'T':
return revlist.replace('T','A',1000)
elif item == 'G':
return revlist.replace('G','C',1000)
elif item == 'C':
return revlist.replace('C','G',1000)
else:
pass
structures('ATTTGCCCTA')
# below is the second way I'm trying to code it
def structures(seq):
revlist = seq[::-1]
old = ['A','T','G','C']
new = ['T','A','C','G']
for item in revlist:
if item == 'A':
return revlist.replace(old[0],new[0])
elif item == 'T':
return revlist.replace(old[1],new[1])
elif item == 'G':
return revlist.replace(old[2],new[2])
elif item == 'C':
return revlist.replace(old[3],new[3])
else:
pass
structures('ATTTGCCCTA')
The method str.replace is meant to replace a single substring by another substring. Keep in mind that having multiple str.replace calls is inefficient since it means traversing your string many times while one would suffice.
To translate characters, you should use str.translate.
def dna_complement(dna):
translation = str.maketrans({'A': 'T', 'T': 'A', 'C': 'G', 'G': 'C'})
return dna.translate(translation)[::-1]
print(dna_complement('AGTC'))
Output
GACT
def structures(dna):
revlist = ''
for item in dna:
if item == 'A':
revlist = 'T' + revlist
elif item == 'C':
revlist = 'G' + revlist
elif item == 'G':
revlist = 'C' + revlist
elif item == 'T':
revlist = 'A' + revlist
return revlist
This code seems to work good. Instead of reversing the list, I researched another way of adding the information in reverse order which equates to the same thing. Credit to github

FizzBuzz with commas instead of newlines

def fizz_buzz(i):
if i % 15 == 0:
return ("FizzBuzz")
elif i % 5 == 0:
return ("Buzz")
elif i % 3 == 0:
return ("Fizz")
else:
return (i)
for i in range(1, 21):
print(fizz_buzz(i))
Where and how would do a new line command here with commas?
Trying to get an output like this: 1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz,16,17,Fizz,19, Buzz
but sideways and with commas.
Pass end=',' to print()
def fizz_buzz(i):
if i % 15 == 0:
return ("FizzBuzz")
elif i % 5 == 0:
return ("Buzz")
elif i % 3 == 0:
return ("Fizz")
else:
return (i)
for i in range(1, 21):
print(fizz_buzz(i), end=',')
# prints
1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz,16,17,Fizz,19,Buzz,
If you do not want the trailing comma, end the range at 20 and follow with print(fizz_buzz(20))
Consider making a list & joining the elements with a comma. There are some great examples here.
For example:
def fizz_buzz(i):
# your code
my_list = []
for i in range(1,21):
my_list.append( str(fizz_buzz(i)) )
print ",".join(my_list)
There are more elegant ways of doing this -- using generators &c, as in the linked answer --, but this simple code will do what you want. Note that the join() method accepts string only, hence the str() in the list.append(); alternatively you could ensure that your fizz_buzz function returns strings regardless.

Resources