Thinking Recursively when it comes to list manipulation - python

from random import *
def Number(N):
if N>0:
return [ choice( [0,1] ) for i in range(N)]
else:
return ("Only Positive #'s!")
How would I do this recursively?
Let's say N=5, so [0,1,2,3,4] for each # to be replaced with either a 0 or a 1. I just can't seem to wrap my head around doing this list manipulation recursively.

Here's one option:
from random import choice # don't use * imports
def Number_recursive(N):
if N < 0:
raise ValueError('N must be positive')
if N == 0:
return []
return [choice((0, 1))] + Number_recursive(N-1)
Note the raising of an error rather than returning a string; this tells the caller more directly that something went wrong.

I don't understand how recursion will help here. How about just simplifying it like this:
from random import choice
def binary_list(length):
return [choice([0, 1]) for x in range(0, length)]

Related

While Loop true and false for approximation of roots

I'm a bit new to programming, and I'm trying to create a root-approximating code. Namely, I'm doing something similar to Newton's method in calculus. The idea is, I'm going to input in a big value, subtract until I know I've passed the root, and then add a smaller quantity until I've passed the root, and iterate until I'm in some comfortable error region.
Here's some pseudo code:
def approx(a,b,i):
while ((1/2)**i) >= (1/2)**10:
while (another function is true):
modify values, record root = r
while (the same function above is false):
modify values, record root = r
return approx(a,b,i+1)
return(a,b,r)
This does not seem to work in Python, so I was wondering if anyone could point me in the correct direction.
Edit: included my actual code:
from fractions import *
from math import sqrt
from math import fabs
def pweight(c,d):
if d > c:
return pweight(d,c)
else:
return [c+d,c,d]
def eweight(a,b):
if a == b:
return [a]
elif b > a:
return eweight(b,a)
else:
return [b] + eweight(a-b,b)
def weight(a,b,c,d):
if a*b/2 > c*d:
print("No Embedding Exists")
return (False)
else:
return (True, [c+d]+sorted((pweight(c,d) + eweight(a,b))[1:], reverse=True))
def wgt(a,b,c,d):
return ([c+d]+sorted((pweight(c,d) + eweight(a,b))[1:], reverse=True))
def red(a,i,k):
d=a[0]-a[1]-a[2]-a[3]
if any(item < 0 for item in a[1:]):
# print ("No Embedding Exists")
return (False, i)
elif d >= 0:
# print ("Embedding Exists! How many iterations?")
# print(i)
return (True, i)
elif d<0:
a=[a[0]+d,a[1]+d,a[2]+d,a[3]+d]+a[4:]
a=[a[0]]+sorted(a[1:],reverse=True)
k.append(a)
i=i+1
return red(a,i,k)
def works(a,b):
L = sqrt(a/(2*b))
w = weight(1,a,L,L*b)
return w[0] and red(w[1],0,[])
def inf(a,b,i):
while ((1/2)**(i+1)) >= (1/2)**(10)):
while works(a,b):
a = a - (1/2)**i
L = sqrt(a/(2*b))
while not works(a,b):
a = a + (1/2)**(i+1)
L = sqrt(a/(2*b))
return inf(a,b,i+1)
return (a,b,L)
I want to input in "inf(9,1,0)" and have this code return something close to (255/32,1,sqrt(255/64)). The main problem is the "while works(a,b):" and "while not works(a,b):" in the function "inf(a,b,i)." I want the function to alternate between the "while works" and "while not works" until i=9.
Any sort of general idea would be appreciated (namely, how do you do some sort of alternating function within a while loop).
If you want to alternate between them, don't put them each in their own while loops, put
while i < 9:
if works(a, b):
do something
if not works(a, b):
do something else
And whatever you test in your while conditions needs to be something that changes somewhere in the loop. Otherwise you'll get an infinite loop.

recursive function python 3 'maximum recursion depth exceeded'

I am creating a collatz sequence with a recursive function below:
def collatz(n):
if n%2 == 0:
return int(n/2)
else:
return int((3 * n)/2)
From what I understand, a recursive function is a function that basically calls itself. Below I have attempted creating the recursive function with the following:
def collatz(x):
if x == 1:
"Done"
print(x)
x = collatz(x)
return(x)
Where essentially the variable x continues to get passed into the collatz function I defined until it gets to 1. However, every time I run the recursive function it prints 'x' repeatedly and then I get the
collatz(3)
'RecursionError: maximum recursion depth exceeded in comparison'
Which I understand is an infinite loop essentially. I thought by reassigning it to x to the results of the first collatz() it would return the new value and continue till it hit '1' but I can't seem to quite get there.
Any help/tips/advice would be great! Thanks!
Recursive functions have what's known as a "base case" and what's known as a "recursive case." The base case is when you should stop recursing and return an answer.
In this case, the base case is when x==1
def collatz(x):
if x == 1:
return x
and the recursive case is the rest of the time
# continuing from above
else:
if n % 2 == 0:
return collatz(int(n//2))
else:
return collatz(n*3 / 2) # sicut. Note that the collatz sequence
# uses 3n+1 here, not 3n/2 as in the question
N.B. that I change the effective value of x in the next loop through collatz before returning the result of that new call. If you don't, and simply return collatz(x), you'll never reach your base case and recurse forever.
#Roee Gavirel
Here is the final answer based on his answer above:
def collatz(x):
if x == 1:
"Done"
elif x%2 == 0:
x = int(x/2)
print(x)
collatz(x)
else:
x = int((3*x)+1)
print(x)
collatz(x)
collatz(3)
Thanks for all the help!
You show two different implementations of the same function collatz, while you need to combine them.
def collatz(n):
if x == 1:
"Done"
print(x)
if n%2 == 0:
collatz(int(n/2))
else:
collatz(int((3 * n)/2))

How to check elements created by generator when debugging a python project?

I use PyCharm to realize a program which is aimed to generate primes. Code like this:
def _odd_iter():
n = 1
while True:
yield n
n = n + 2
def _not_divisible(n):
return lambda x: x % n > 0
def primes():
it = _odd_iter()
yield 2
while True:
i = next(it)
yield i
it = filter(_not_divisible, it) # !!!!!!!!!!don't know how it works!!!!!!!!!!
for n in primes():
if n < 1000:
print(n)
else:
break
For me the annotated code is obscure, I dont know how it works and whether it is right, so I add a breakpoint on it and determine to debug. But it is a generator, I cannot see the detail numbers. What can I do?
filter(function or None, iterable) --> filter object
Return an iterator yielding those items of iterable for which function(item) is true. If function is None, return the items that are true.
You can't see the details because it returns an iterable object, do this to see what it returns:
it = list(filter(_not_divisible, it)) # or next(filter(...))

How can I add the outcome of a function to a list in python?

def b():
a = int(input("Look up to: ")) // set the range to scan for primes
for num in range(0, a):
if prime(num) == True:
print(num)
print("adding to list")
return num
list = [num]
list.append(num)
else:
print(num, "is not a prime")
So how can I append the outcome to "list" for each new prime?
Forgot to mention the function to check if num is prime:
def prime(num):
for j in range (2, num):
if (num % j) == 0 :
return False
return True
Few points:
Once you return is executed, the value it is applied to is returned to whoever called the function and the code after return never executes.
You're shadowing the built-in function list() which returns a new list by calling a local variable list.
The list is constantly reconstructed by calling [num] which is a shorthand for creating a new list containing only num. What you want to do is update it using append.
Fixing the code, it may look something like:
def get_primes():
a = int(input("Look up to: "))
# 'primes' is a more suitable name for a list of primes
# we're only creating the list *once*, and we're not shadowing 'list'
primes = list()
for candidate in range(0, a):
if prime(candidate) == True:
print(candidate)
print("adding to list")
primes.append(candidate)
else:
print(num, "is not a prime")
# use return to return a result
return primes
You can test this by calling get_primes().
Tip: you could use filter to do the same thing get_primes does:
a = int(input("Look up to: "))
print(filter(prime, range(0, a)))
A minor note about the difference between list and [] is that you can change list's behaviour, which gives finer control, while []'s generated code calls BUILD_LIST directly (harder to change):
>>> dis.dis(lambda: [])
1 0 BUILD_LIST 0
3 RETURN_VALUE
>>> dis.dis(lambda: list())
1 0 LOAD_GLOBAL 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
It really does not matter in this case, but #Thrustmaster suggested using [] in the comments since it some may see it as cleaner.
Oh, lot of minor syntax errors. Let me list them down..
Python comments do not start with //, but with #. Ref. code line no: 2
list is a keyword in python, you should not use that in your variable declaration. Line ref: 8.
After you do a return, the code after that line will not be executed. Line Ref: 7.
You should not initialize list inside the for loop. It is getting initialized in every iteration.
Instead of if prim(num) == True:, you can simply write if prim(num):.
That said, the correct code should look as follows:
def b():
a = int(input("Look up to: ")) # set the range to scan for primes
primes = [] #Your list
for num in range(0, a):
if prime(num):
print(num)
print("adding to list")
primes.append(num)
else:
print(num, "is not a prime")
return primes
Hope it helps .. :)
Your code looks to be a mix of C and Python (don't use // as comments).
I assume your program is looking for prime numbers up to n. Here is how one might go about implementing this:
import math
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
for i in range(3, int(math.sqrt(n)) + 1, 2):
if n % i == 0:
return False
return True
def find_primes(a, b):
primes = []
for i in range(a, b):
if is_prime(i):
primes.append(i)
return primes
You're almost there. The strange thing about your code is where you've placed the return statement. Try this:
def b():
primesList = []
a = int(input("Look up to: "))
for num in range(0, a):
if prime(num) == True:
print(num)
print("adding to list")
primesList.append(num)
else:
print(num, "is not a prime")
return primesList
Notice that your original return statement would have ended your function early, in fact even before your list would have had the chance to append any prime number at all. The other important point here is that you should never shadow a built-in type (list in this case), or other built-in functions (like map, sorted, etc.).
It's also enough to simply initialize the primesList once and append the num integers inside the for loop.
The other answers are good and address the main issue that you had with rebinding your list variable and failing to return the primes list from function b().
I think it's worth mentioning that a list comprehension can be used to succinctly code the prime list generation:
def prime(num):
for j in range (2, num):
if (num % j) == 0 :
return False
return True
def get_primes(low, high):
return [n for n in range(low, high+1) if prime(n)]
>>> a = input("Look up to: ")
11
>>> get_primes(0, a)
[0, 1, 2, 3, 5, 7, 11]
>>> get_primes(5, a)
[5, 7, 11]
Notes:
Passing the "up to" value into the function is more flexible than
prompting for it in the function.
"Up to" should be inclusive, e.g. get_primes(0, 11) should include 11 in the result. Therefore you need to add one to the upper value when calling range().
Passing low and high allows you to generate primes for arbitrary ranges.
You can wrap the list comprehension with set() to have the result returned as a set.

Instead of continue, rerun function

I'm wondering how to do the following in Python.
If I have a function with a for loop, it is possible to with an if statement to skip certain numbers.
This is an implementation of fisher-yates d got from activestate.com.
import random
def shuffle(ary):
a=len(ary)
b=a-1
for d in range(b,0,-1):
e=random.randint(0,d)
if e == d:
continue
ary[d],ary[e]=ary[e],ary[d]
return ary
Now continue simply goes to the next value for d. How can I, instead of doing continue, rerun the function with the original parameter ary?
Note that the function is just some example code, I'm curious on how to do this in general.
Also, maintaining a copy of the array might not be possible if the list is big, so thats not really a solution imo.
This is a common recursive pattern. However, your case is a little different than usual because here you need to make a copy of your input list to use when you recurse if the shuffling fails.:
import random
def shuffle(ary):
initial = ary[:]
a=len(ary)
b=a-1
for d in range(b,0,-1):
e=random.randint(0,d)
if e == d:
return shuffle(initial)
ary[d],ary[e]=ary[e],ary[d]
return ary
ary = [1,2,3,4,5,6]
print shuffle(ary)
Also note that Wikipedia gives a (non-recursive) python implementation of the very similar Sattolo's algorithm.
from random import randrange
def sattoloCycle(items):
i = len(items)
while i > 1:
i = i - 1
j = randrange(i) # 0 <= j <= i-1
items[j], items[i] = items[i], items[j]
return
If I read the article correctly, to re-acquire Fisher-Yates, you'd just do one simple change:
from random import randrange
def FisherYates(items):
i = len(items)
while i > 1:
i = i - 1
j = randrange(i+1) # 0 <= j <= i
items[j], items[i] = items[i], items[j]
return
def function(list):
len(list)-1
for i in range(len(list)-1,0,-1):
e= randint(0,i)
while e > i:
e= randint(0,i)
"do something to the list"
return array
?
def function(list):
for i in (a for a in range(len(list)-1,0,-1) if randint(0,a) > a):
#do something with list
#do something else with remainder.
Not exactly what you asked for. Just wanted to remind you of this possibility.
you can copy the parameter to a temp variable. then call the function with the temp variable and use return;
def function(list):
listCopy = list;
len(list)-1
for i in range(len(list)-1,0,-1):
e= randint(0,i)
if e > i:
return function(listCopy)
else
"do something with the list"
return array

Categories