The aim is to add two given lists through recursion. For example
[1,2,3] + [4,5,6] = [5,7,9]
I am getting an
int object is not iterable
error.
Here is the code:
def seqaddr(l1,l2):
if len(l1)==1:
l1[0]=l1[0]+l2[0]
return l1
else:
return seqaddr(l1[:len(l1)-1],l2[:len(l2)-1]) + list(l1.pop()+l2.pop())
seqaddr([1,2,3],[4,5,6])
You can't convert an number to a list using list(n). You should use a list literal. Change the following line:
return seqaddr(l1[:len(l1)-1],l2[:len(l2)-1]) + list(l1.pop()+l2.pop())
to
return seqaddr(l1[:len(l1)-1],l2[:len(l2)-1]) + [l1.pop() + l2.pop()]
Update: Your function mutates the original arguments, which is generally considered a Bad Thing™. An idempotent version can be written as:
def seqaddr(l1, l2):
if len(l1) == 1:
return [l1[0] + l2[0]]
else:
return seqaddr(l1[:-1], l2[:-1]) + [l1[-1] + l2[-1]]
A further simplification to the last line of code in the answer by Selcuk
def seqaddr(l1,l2):
if len(l1)==1:
l1[0]=l1[0]+l2[0]
return l1
else:
return seqaddr(l1[:-1],l2[:-1]) + [l1.pop() + l2.pop()]
Related
I need help with recursion I have a code right here which turns an integer into a list of strings. However, I'm struggling to make it recursive. Here is what I have so far.
def turnList( a ):
b = str(a)
c = []
for digit in b:
c.append(digit)
return c
For a recursive function you need a base case, i.e. when we have finished and no longer need to recurse and a generic recursive case
def turnList(a):
a=str(a)
if len(a)==1:
return [a]
else:
return [a[0]] + turnList(a[1:])
Our base case is when our recursive function gets a string of length one. And our recursive case returns the first value in its input as a string (in a list) combined with the list of all the 'future' recursive strings.
Start with a base case, in this case empty list for zero, then define the recursive behavior.
def turnList(a):
if a == 0: # base case
return []
a,d = divmod(a,10) # strip off last digit
return turnList(a) + [str(d)] # recurse
print(turnList(123))
Output:
['1', '2', '3']
There are multiple ways to do recursion. Here, we adjust bIndex.
b = "hello"
def turnList(c, bIndex):
if len(b) == bIndex:
return c
return turnList(c + [b[bIndex]],bIndex+1)
print(turnList([],0))
global an
an = []
def turnList(a):
global an
b=str(a)
an.append(b[len(b)-1])
try:
return turnList(int(b[:len(b)-1]))
except ValueError as e:
an.reverse()
return an
m = turnList(10)
print(m)
this might be the best i've ever written
I'm learning data and algorithm, here is the question I met
Question:Write a short recursive Python function that takes a character string s and
outputs its reverse. For example, the reverse of pots&pans would be
snap&stop .
a="pots&pans"
b=a.split("&")
c=[]
c=list(b)
def reverse(data,leng,leng2,index,count):
rev=(leng-1)-count
if count<leng/2:
temp=data[index][count]
data[index][count]=data[index][rev]
data[index][rev]=temp
if index==leng2:
print(data[index-1]+"&"+data[index])
return reverse(data,leng,leng2,index+1,count)
reverse(c,4,2,0,0)
I got an error here
TypeError: 'str' object does not support item assignment
My initial thought is that str is immutable. So it is better to store it in an list and do the operations. However, it met some problem when I trying to assign str to a list. Any solution to this?
Try this:
a="pots&pans"
b=a.split("&")
def reverse(word):
if not word:
return ""
return reverse(word[1:]) + word[0]
result = reverse(b[1]) + "&" + reverse(b[0])
print(result)
If you want one recursion to also reverse all the words position:
a="pots&pans&hello&hi"
b=a.split("&")
def reverse(lis):
if not lis:
return ""
if type(lis) == list and len(lis) == 1:
return reverse(lis[0])
if type(lis) == str:
return reverse(lis[1:]) + lis[0]
if type(lis) == list:
return reverse(lis[1:]) + "&" + reverse(lis[0])
print(reverse(b))
One recursive approach would be to append the first character to the reverse of the rest of the string:
def rev(s): return rev(s[1:])+s[0] if s else ""
output:
rev("pots&pans")
'snap&stop'
You could also do this without indexing using parameter unpacking:
def rev(first,*rest): return rev(*rest)+first if rest else first
rev(*"pots&pans")
'snap&stop'
Try this:
a="pots&pans"
def reverse(a_string):
`letter_list = list(a_string)`
`letter_list.reverse()`
`return(''.join(letter_list))`
print(reverse(a))
I'm trying to take a list and reverse the middle elements only, not the first and last. I keep running into a nonetype error and don't understand why.
def reverse_middle(nums):
a = nums[0]
b = nums[-1]
interior = nums
interior.pop()
interior.pop(0)
final = interior.reverse()
final.insert(0, a)
final.append(b)
return final
The reverse method of list reverses the list but doesn't return the reversed list but None instead: the reverse is made in-place.
def reverse_middle(nums):
a = nums[0]
b = nums[-1]
interior = nums
interior.pop()
interior.pop(0)
interior.reverse()
final = interior
final.insert(0, a)
final.append(b)
return final
And for a more concise code use this:
def reverse_middle(nums):
a = nums[0]
b = nums[-1]
interior = nums[1:-1]
interior.reverse()
final = [a] + interior + [b]
return final
And even more concise
def reverse_middle(nums):
interior = nums[1:-1]
interior.reverse()
return [nums[0]] + interior + [nums[-1]]
interior.reverse() does so in-place (i.e. interior is reversed) and returns nothing to final.
That's why, final is None. None object has no method called insert.
I am making a recursive function that slices string until it is empty. When it is empty it alternatively selects the characters and is supposed to print or return the value. In this case I am expecting my function to return two words 'Hello' and 'World'. Maybe I have got it all wrong but what I don't understand is that my function doesn't let me print or return string. I am not asking for help but I'd like some explanation :) thanks
def lsubstr(x):
a= ''
b= ''
if x == '':
return ''
else:
a = a + x[0:]
b = b + x[1:]
lsubstr(x[2:])
#print (a,b)
return a and b
lsubstr('hweolrllod')
so I changed my code to this:
def lsubstr(x):
if len(x) <1:
return x
else:
return (lsubstr(x[2:])+str(x[0]),lsubstr(x[2:])+str(x[1]))
lsubstr('hweolrllod')
and what I am trying to make is a tuple which will store 2 pairs of characters and concatenate the next ones,
the error I get is
TypeError: Can't convert 'tuple' object to str implicitly
what exactly is going wrong, I have checked in visualization, it has trouble in concatenating.
The and keyword is a boolean operator, which means it compares two values, and returns one of the values. I think you want to return a tuple instead, like this:
...
return (a, b)
And then you can access the values using the indexing operator like this:
a = lsubstr( ... )
a[0]
a[1]
Or:
word1, word2 = lsubstr( ... )
my code consists of me recreating the function 'filter()' and using it with a function to filter words longer than 5 characters. It worked with the actual function filter when I tried it btw...I'm using python 3+
def filter1(fn, a):
i = 0
while i != len(a):
u = i - 1
a[i] = fn(a[i], a[u])
i += 1
return a
def filter_long_words(l):
if len[l] > 5:
return [l]
listered = ['blue', 'hdfdhsf', 'dsfjbdsf', 'jole']
print(list(filter1(filter_long_words, listered)))
getting error
TypeError: filter_long_words() takes 1 positional argument but 2 were given
You are passing two parameters to fn (which refers to filter_long_words) here:
a[i] = fn(a[i], a[u])
But filter_long_words only accepts one parameter.
Notes:
You can loop through lists using for item in my_list, or if you want index as well for index, item in enumerate(my_list).
I think you might get an IndexError since u will be -1 in the first round of your loop.
The filter function can also be expressed as a list comprehension: (item for item in listered if filter_long_words(item))
My version of filter would look like this, if I have to use a for loop:
def my_filter(fn, sequence):
if fn is None:
fn = lambda x: x
for item in sequence:
if fn(item):
yield item
Since you have stated that you are using Python 3, this returns a generator instead of a list. If you want it to return a list:
def my_filter(fn, sequence):
if fn is None:
fn = lambda x: x
acc = []
for item in sequence:
if fn(item):
acc.append(item)
return acc
If you don't need to use a for loop:
def my_filter(fn, sequence):
if fn is None:
fn = lambda x: x
return (item for item in sequence if fn(item))
Your're calling fn with 2 parameters in filter1(fn, a), and since you've passed filter_long_words() to filter1 as fn, that triggers the error.
But there's more weird stuff:
I don't understand the magick of filter1 or what you were trying to
accomplish, but it seems to me that you don't have a clear idea what to do.
But if you want to mimic (somehow) how filter works, you have to return a
list which contains only items for which the fn function returns true. When
you know this, you can rewrite it - here are a few suggestions for rewrite
# explicit, inefficient and long, but straightforward version:
def filter1(fn, a):
new_list = []
for item in a:
if fn(item):
new_list.append(item):
return new_list
# shorter version using list comprehensions:
def filter1(fn, a):
return [item for item in a if fn(item)]
The filter_long_words function is wrong too - it should return True or
False. The only reason why it could work is because any non-empty list is
treated as True by python and default return value of a function is None,
which translates to False. But it's confusing and syntactically wrong to use
len[l] - the proper usage is len(l).
There are a few suggestions for rewrite, which all returns explicit boolean
values:
# unnecessary long, but self-explanatory:
def filter_long_words(l):
if len(l) > 5:
return True
else
return False
# short variant
def filter_long_words(l):
return len(l) > 5
You are calling "filter_long_words" with 2 parameter => fn(a[i], a[u]) also there is an error
def filter_long_words(l):
if **len[l]** > 5:
return [l]
len is builtin method it should be len(l)