def recurse( aList ):
matches = [ match for match in action if "A" in match ]
uses = " ".join(matches)
return f"Answer: { aList.index( uses )"
This is the non recursive method. I just couldn't figure out how to implement recursion in regards of lists.
Output should be Answer: n uses.
Can anybody help.
Recursion is a bad fit for this problem in Python, because lists aren' really recursive data structures. But you could write the following:
def recurse(aList):
if not aList:
return 0
return ("A" in aList[0]) + recurse(aList[1:])
Nothing in an empty list, by definition, contains "A". Otherwise, determined if "A" is in the first element of the list, and add 1 or 0 as appropriate (remember, bools are ints in Python) to the number of matches in the rest of the list.
The recursive function should only deal with the count itself; let the caller of the recursive function put the count into a string:
print("Answer: {recurse(aList)} uses"}
Related
My first attempt at writing a recursive function that lists all permutations of strings characters.
If I set a list to be empty, then add the results to this list, I find that the list gets reset to empty with each call of the function.
I know what I have at the moment is also wrong as the for loop will be broken by the return statement. But this is where I am stuck, how to save the results i.e. each separate permutation, without having the list reset to empty with each call? I am not allowed use global variables, this is an exercise from an MIT open Courseware class.
Also would like to know if my method will even work? not sure if how I have sliced the string up will work.
Can anyone shed light on how I can make a list of all the permutations within the function? and if my method even has any chance of working?
def get_permutations(sequence):
if len(sequence) == 1:
return sequence
else:
return (sequence[i] + get_permutations(sequence[0:i-1] + sequence[i +
1 : len(sequence)]) for i in range(len(sequence)))
Now the output is
<generator object get_permutations.<locals>.<genexpr> at 0x102b3b9d0>
You can't return more than once! Instead of returning each value from inside of a loop, you want to build a list and return that. That would look something like this:
def get_permutations(sequence):
if len(sequence) == 1:
# base case
return sequence
# Each recursive call needs to be on a subset of sequence so it gets
# smaller each time and eventually reaches the base case...
return [
sequence[i] + get_permutations(sequence[0:i-1] + sequence[i+1:len(sequence)])
for i in range(len(sequence))
]
There are still some errors here in how you're reducing to your base case and how you're building the list, but hopefully this gets you pointed in the right direction!
Since the function is supposed to return a list of permutations, you should use a nested for clause in the list comprehension to iterate through the returning list from the recursive call to append to the current value at index i. Also, in the base case the function should also return a list of string characters, even it's a list of just one character:
def get_permutations(sequence):
if len(sequence) == 1:
return [sequence]
return [
sequence[i] + s
for i in range(len(sequence))
for s in get_permutations(sequence[:i] + sequence[i + 1:])
]
so that:
get_permutations('abc')
returns:
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
I recently studied a python recursion function and found that the recursion stops when it uses element in []. So I made a simple test function, found that there is even no print out. So how can I understand the element in []? Why does the function stop when referring to element in []?
b=1
def simple():
for i in []:
print('i am here')
return i+b
a = simple()
Python's in keyword has two purposes.
One use in as part of a for loop, which is written for element in iterable. This assigns each value from iterable to element on each pass through the loop body. This is how your example function is using in (though since the list you're looping over is empty, the loop never does anything).
The other way you can use in is as an operator. An expression like x in y tests if element x is present in container y. (There's also a negated version of the in operator, not in. The expression x not in y is exactly equivalent to not (x in y).) I suspect this is what your recursive code is doing. This would also not be useful to do with an empty list literal (since an empty list by definition doesn't contain anything), but I'm guessing the real recursive function is a bit more complicated.
As an example of both uses of in, here's a generator function that uses a set to filter out duplicate items from some other iterable. It has a for loop that has in, and it also uses in (well, technically not in) as an operator to test if the next value from the input iterator is contained in the seen set:
def unique(iterable):
seen = set()
for item in iterable: # "in" used by for loop
if item not in seen: # "in" used here as an operator
yield item
seen.add(item)
A recursive function calls itself n-number of times, then returns a terminating value on the last recursion that backs out of the recursive stacks.
Example:
compute the factorial of a number:
def fact(n):
# ex: 5 * 4 * 3 * 2 * 1
# n == 0 is your terminating recursion
if n == 0:
return 1
# else is your recursion call to fact(n-1)
else:
return n * fact(n-1)
In your example, there is no recursive call to simple() within the function, nor are there any element inside the empty list [] to step through, therefore your for loop never executed
Its concerned about mechanism of 'for loop'.
Superficially, the iterator you want to travese (which is "[]" in you example) has a length of 0, so the body of the loop (which include "print" an so on) will not be executed.
Hope it helps.
I'm currently working with a recursive function in Python, and I've run into a wall. As titled, the problem is to return the maximum depth of an arbitrarily nested list.
Here is what I have so far:
def depthCount(lst):
'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
var = 0
if len(lst) > 0:
if type(lst[0]) == list:
var += 1
depthCount(lst[1:])
else:
depthCount(lst[1:])
else:
return var
I feel that the problem is with my recursive calls (this may be obvious). It will indeed return var when the list has reached the end, but when I have a nonempty list, things go awry. Nothing is returned at all.
Am I slicing wrong? Should I be doing something before the slice in the recursive call?
The problem may also be with my base case.
If they are just nested lists, e.g., [[[], []], [], [[]]], here's a nice solution:
def depthCount(lst):
return 1 + max(map(depthCount, lst), default=0)
Here's a slight variation you could use if you don't use Python 3.4, where the default argument was introduced:
def depthCount(lst):
return len(lst) and 1 + max(map(depthCount, lst))
They also differ by how they count. The first considers the empty list to be depth 1, the second to be depth 0. The first one is easy to adapt, though, just make the default -1.
If they're not just nested lists, e.g., [[[1], 'a', [-5.5]], [(6,3)], [['hi']]]), here are adaptions to that:
def depthCount(x):
return 1 + max(map(depthCount, x)) if x and isinstance(x, list) else 0
def depthCount(x):
return int(isinstance(x, list)) and len(x) and 1 + max(map(depthCount, x))
Make sure you understand how the latter one works. If you don't know it yet, it'll teach you how and works in Python :-)
Taking the "purely recursive" challenge:
def depthCount(x, depth=0):
if not x or not isinstance(x, list):
return depth
return max(depthCount(x[0], depth+1),
depthCount(x[1:], depth))
Granted, the extra argument is slightly ugly, but I think it's ok.
It will indeed return var when the list has reached the end, but when I have a nonempty list, things go awry. Nothing is returned at all.
That's because you have no return statement, except in the else base case for an empty list. And if you fall off the end of the function without hitting a return, that means the function returns None.
But you have another problem on top of that. You're starting var = 0, then possibly doing var += 1… but you're not passing that down into the recursive calls, or using any result from the recursive calls. So the recursive calls have no useful effect at all.
What you probably meant is something like this:
def depthCount(lst):
'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
if len(lst) > 0:
if type(lst[0]) == list:
return 1 + depthCount(lst[1:])
else:
return depthCount(lst[1:])
else:
return 0
But this still isn't actually right. The depth count of a list is 1 more than the depth count of its deepest element. Just checking its second element won't do you any good; you need to check all of them. So, what you really want is something like this:
def depthCount(lst):
'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
if isinstance(lst, list):
return 1 + max(depthCount(x) for x in lst)
else:
return 0
If you want to replace that iterative for x in lst with a second layer of recursion, of course you can, but I can't see any good reason to do so; it just makes the code more complicated for no reason. For example:
def max_child_count(lst):
if lst:
return max(depth_count(lst[0]), max_child_count(lst[1:]))
else:
return 0
def depth_count(lst):
if isinstance(lst, list):
return 1 + max_child_count(lst)
else:
return 0
This may still not be right. It definitely does the right thing for, e.g., [1, [2,3], [4, [5]]]. But what should it do for, say, []? I can't tell from your question. If it should return 0 or 1, you'll obviously need to change the if appropriately. If that's illegal input, then it's already doing the right thing. (And that should also answer the question of what it should do for, e.g., [[[], []], [], [[]]], but make sure you think through that case as well.)
So, essentially, the data structure that you're referring to is a k-ary tree, also known as n-ary tree, with arbitrary branching. Here's the code for determining the max. depth of a n-ary tree with arbitrary branching.
def maxdepth(tree):
if isleaf(tree):
return 1
maximum = 0
for child in children(tree):
depth = maxdepth(child)
if depth > maximum:
maximum = depth
return maximum + 1
You can see the code in action with different test inputs here.
Please tell me why this sort function for Python isnt working :)
def sort(list):
if len(list)==0:
return list
elif len(list)==1:
return list
else:
for b in range(1,len(list)):
if list[b-1]>list[b]:
print (list[b-1])
hold = list[b-1]
list[b-1]=list[b]
list[b] = hold
a = [1,2,13,131,1,3,4]
print (sort(a))
It looks like you're attempting to implement a neighbor-sort algorithm. You need to repeat the loop N times. Since you only loop through the array once, you end up with the largest element being in its place (i.e., in the last index), but the rest is left unsorted.
You could debug your algorithm on your own, using pdb.
Or, you could use python's built-in sorting.
Lets take a look at you code. Sort is a built in Python function (at least I believe it is the same for both 2.7 and 3.X) So when you are making your own functions try to stay away from name that function with inbuilt functions unless you are going to override them (Which is a whole different topic.) This idea also applies to the parameter that you used. list is a type in the python language AKA you will not be able to use that variable name. Now for some work on your code after you change all the variables and etc...
When you are going through your function you only will swap is the 2 selected elements are next to each other when needed. This will not work with all list combinations. You have to be able to check that the current i that you are at is in the correct place. So if the end element is the lowest in the List then you have to have it swap all the way to the front of the list. There are many ways of sorting (ie. Quick sort, MergeSort,Bubble Sort) and this isnt the best way... :) Here is some help:
def sortThis(L):
if (len(L) == 0 or len(L) == 1):
return list
else:
for i in range(len(L)):
value = L[i]
j = i - 1
while (j >= 0) and (L[j] > value):
L[j+1] = L[j]
j -= 1
L[j+1] = value
a = [1,2,13,131,1,3,4]
sortThis(a)
print a
Take a look at this for more sorting Fun: QuickSort MergeSort
If it works, it would be the best sorting algotithm in the world (O(n)). Your algorithm only puts the greatest element at the end of the list. you have to apply recursively your function to list[:-1].
You should not use python reserved words
As an exercise, i implemented the map function using recursion in python as follows:
#map function that applies the function f on every element of list l and returns the new list
def map(l,f):
if l == []:
return []
else:
return [f(l[0])] + map(l[1:],f)
I am aware of the fact that python does not support tail recursion optimization, but how would i go about writing the same function in a tail recursive manner ?.
Please Help
Thank You
Tail recursion means you must be directly returning the result of a recursive call, with no further manipulation.
The obvious recursion in map is to compute the function on one element of the list, then use a recursive call to process the rest of the list. However, you need to combine the result of processing one element with the result of processing the rest of the list, which requires an operation after the recursive call.
A very common pattern for avoiding that is to move the combination inside the recursive call; you pass in the processed element as an argument, and make it part of map's responsibility to do the combining as well.
def map(l, f):
if l == []:
return []
else:
return map(l[1:], f, f(l[0]))
Now it's tail recursive! But it's also obviously wrong. In the tail recursive call, we're passing 3 arguments, but map only takes two arguments. And then there's the question of what do we do with the 3rd value. In the base case (when the list is empty), it's obvious: return a list containing the information passed in. In the recursive case, we're computing a new value, and we have this extra parameter passed in from the top, and we have the recursive call. The new value and the extra parameter need to be rolled up together to be passed into the recursive call, so that the recursive call can be tail recursive. All of which suggests the following:
def map(l, f):
return map_acc(l, f, [])
def map_acc(l, f, a):
if l == []:
return a
else:
b = a + [f(l[0])]
return map_acc(l[1:], f, b)
Which can be expressed more concisely and Pythonically as other answers have shown, without resorting to a separate helper function. But this shows a general way of turning non-tail-recursive functions into tail recursive functions.
In the above, a is called an accumulator. The general idea is to move the operations you normally do after a recursive call into the next recursive call, by wrapping up the work outer calls have done "so far" and passing that on in an accumulator.
If map can be thought of as meaning "call f on every element of l, and return a list of the results", map_acc can be thought of as meaning "call f on every element of l, returning a list of the results combined with a, a list of results already produced".
This will be an example of the implementation of the built-in function map in tail recursion:
def map(func, ls, res=None):
if res is None:
res = []
if not ls:
return res
res.append(func(ls[0]))
return map(func, ls[1:], res)
But it will not solve the problem of python not having support of TRE which mean that the call stack of each function call will be hold at all the time.
This seems to be tail recursive:
def map(l,f,x=[]):
if l == []:
return x
else:
return map(l[1:],f,x+[f(l[0])])
Or in more compact form:
def map(l,f,x=[]):
return l and map(l[1:],f,x+[f(l[0])]) or x
not really an answer, sorry, but another way to implement map is to write it in terms of a fold. if you try, you'll find that it only comes out "right" with foldr; using foldl gives you a reversed list. unfortunately, foldr isn't tail recursive, while foldl is. this suggests that there's something more "natural" about rev_map (map that returns a reversed list). unfortunately i am not well enough educated to take this any further (i suspect you might be able to generalise this to say that there is no solution that doesn't use an accumulator, but i personally don't see how to make the argument).