How can I fix my function? - python

I am being told.. from comments to fix my function to make it look "cleaner". I've tried alot.. but i don't know how to use llambda to accomplish what I'm trying to do. My code works.. it just isn't what is being asked of me.
Here is my code with suggestions on how to fix it.
def immutable_fibonacci(position):
#define a lambda instead of def here
def compute_fib (previousSeries, ignore):
newList = previousSeries
if len(newList) < 2: # Do this outside and keep this function focused only on returning a new list with last element being sum of previous two elements
newList.append(1)
else:
first = newList[-1]
second = newList[-2]
newList.append(first+second)
return newList
range=[None]*position
return reduce(compute_fib, range, [])
#Above is too much code. How about something like this:
#next_series = lambda series,_ : (Use these instead of the above line)
#return reduce(next_series, range(position - 2), [1, 1])
Anything helps.. I am just confused on how I can implement these suggestions.
Here is what I attempted.
def immutable_fibonacci(position):
range=[None]*position
next_series = lambda series, _ : series.append(series[-1] + series[-2])
return reduce(next_series, range(position - 2), [1, 1])

The append function returns None. You need to return a renewed array
next_series = lambda series: series + [series[-1] + series[-2]]
Also renaming range isn't serving any purpose.
def immutable_fibonacci(position):
next_series = lambda series: series + [series[-1] + series[-2]]
return reduce(next_series, range(position - 2), [1, 1])
This is assuming you only call the function for positions >= 2. Conventionally fib(0) is 0 and fib(1) is 1.

Related

Python - Adding all digits in string

How can i create a function that returns the sum of a string made up of 3 or more digits. For example, if the parameter/string is "13456". How can I return the result of (1*3 + 3*4 + 4*5 + 5*6). Thank you, all help is appreciated. Very new to python.
Another one-liner:
a = '13456'
print(sum([int(x)*int(y) for x, y in zip(a[1:], a[:-1])]))
You just need to go through the string, multiplying the actual value to the next value and add it to a variable to return it later.
def func(param):
ret = 0
for i in range(len(param)-1):
ret = ret + int(param[i]) * int(param[i+1])
return ret
my_string = "12345"
total = 0
for n in range(len(my_string) - 1):
total += int(my_string[n]) * int(my_string[n+1])
This function first turns your string into a list and then applies a map on it to convert all the elements to ints. Finally it uses a loop to access and multiply consecutive elements,
def str_sum(nstr):
nint = list(map(int, list(nstr)));
res = 0;
for i in range(len(nint[:-1])):
res += nint[i]*nint[i+1]
return res
Converting result of map into list using list(map(...)) is redundant in Python 2.7 but necessary in Python 3.X as map returns an object instead of a list.
Use range + sum
l = '13456'
sum([int(l[i])*int(l[i+1]) for i in range(len(l)-1)])
#Output:
#65
with range(len(l)-1), you can get the start, end indexes like below
Output:[0, 1, 2, 3]
Looping through the above list and indexing on list l,
int(l[i])*int(l[i+1]) # gives [1*3, 3*4 , ...]
Summing the output list
sum([1*3, 3*4 , ...]) # gives 65
def func(input):
return sum([int(input[i])*int(input[i+1]) for i in range(len(input)-1)])

Turning Equation Into Function?

I need to turn following equation into a python function.
k = people[i]
i = people[j]
costs[i][j]
costs[j][k]
change = -costs[i][k] - costs[j][l] + costs[i][l] + cost[j][k]
I think what you're looking for is:
def change(i,j,costs,people):
k = people[i]
l = people[j] # was originally i = people[j] but unsure where l comes from otherwise
result = -costs[i][k] - costs[j][l] + costs[i][l] + cost[j][k]
return result
(and then call with:
mychange = change(i,j,costs,people)
)
Note that if my assumption on where l comes from is wrong, change that 3rd line back to i = people[j] and pass in l as well.
Also note that using l as a variable is a bad idea as it's rather hard to tell apart from 1 (and also, using i,j,k,l is bad when you could use a more descriptive value to make it clearer what this means)

I want to sort a list in a method with respect to the method's argument

I have a method and as an argument I enter x and y coordinates of a point and then I calculate the power reached to that [x,y] coordinate from other points and sort them in order of highest power reached to lowest:
def power_at_each_point(x_cord, y_cord):
nodez_list = [nodes_in_room for nodes_in_room in range(1, len(Node_Positions_Ascending) + 1)]
powers_list = []
for each_node in nodez_list:
powers_list.append(cal_pow_rec_plandwall(each_node, [x_cord, y_cord]))
return max(powers_list)
I want to do that in a more pythonic way like key = cal_pow_rec_plandwall but this method takes two arguments and not one.
So how can I do it?
You just need a single call to max which takes a generator as an argument. The lambda expression is just to make things more readable.
def power_at_each_point(x_cord, y_coord):
f = lambda x: cal_pow_rec_plandwall(x, [x_coord, y_coord])
return max(f(each_node) for each_node in xrange(1, len(Node_Positions_Ascending) + 1))
You can replace the generator with a call to itertools.imap:
from itertools import imap
def power_at_each_point(x_coord, y_coord):
f = lambda x: cal_pow_rec_plandwall(x, [x_coord, y_coord])
return max(imap(f, xrange(1, len(Node_Positions_Ascending) + 1)))

How to write all_subsets function using recursion?

Given the function all_subsets(lst), how can I write this function using recursion?
For example of input: [1,2,3], the output should be: [[], [1],[2],[3],[1,2],[1,3],[2,3][1,2,3]]
The assignment is to use recursive function. Please help. This is part of a lab assignment, so I am not graded on this, but at the same time, I am dying to learn how to write this code, and I don't know anyone in my lab class that's figured it out.
So far, I've got:
def all_subsets(b):
if len(b) == 0:
return ''
else:
lst = []
subsets = all_subsets(b[1:])
for i in b:
lst.append([i])
for i in subsets:
if b[0] not in i:
lst.append([b[0]] + i)
for i in subsets:
if b[1] not in i:
lst.append([b[1]] + i)
return lst
It can handle [1,2,3], but it can't handle anything bigger; plus this code also has weird output order
This should work:
def all_subsets(b):
if len(b)==1:
return [[], b] # if set has 1 element then it has only 2 substets
else:
s = all_subsets(b[:-1]) # calculate subsets of set without last element
# and compose remaining subsets
return sorted(s + [e + [b[-1]] for e in s], key=len) # you can omit sorting if you want

counting odd numbers in a list python

This is a part of my homework assignment and im close to the final answer but not quite yet. I need to write a function that counts odd numbers in a list.
Create a recursive function count_odd(l) which takes as its only argument a list of integers. The function will return a count of the number of list elements that are odd, i.e., not evenly divisible by 2.\
>>> print count_odd([])
0
>>> print count_odd([1, 3, 5])
3
>>> print count_odd([2, 4, 6])
0
>>> print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
8
Here is what i have so far:
#- recursive function count_odd -#
def count_odd(l):
"""returns a count of the odd integers in l.
PRE: l is a list of integers.
POST: l is unchanged."""
count_odd=0
while count_odd<len(l):
if l[count_odd]%2==0:
count_odd=count_odd
else:
l[count_odd]%2!=0
count_odd=count_odd+1
return count_odd
#- test harness
print count_odd([])
print count_odd([1, 3, 5])
print count_odd([2, 4, 6])
print count_odd([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144])
Can u help explain what im missing. The first two test harness works fine but i cant get the final two. Thanks!
Since this is homework, consider this pseudo-code that just counts a list:
function count (LIST)
if LIST has more items
// recursive case.
// Add one for the current item we are counting,
// and call count() again to process the *remaining* items.
remaining = everything in LIST except the first item
return 1 + count(remaining)
else
// base case -- what "ends" the recursion
// If an item is removed each time, the list will eventually be empty.
return 0
This is very similar to what the homework is asking for, but it needs to be translate to Python and you must work out the correct recursive case logic.
Happy coding.
def count_odd(L):
return (L[0]%2) + count_odd(L[1:]) if L else 0
Are slices ok? Doesn't feel recursive to me, but I guess the whole thing is kind of against usual idioms (i.e. - recursion of this sort in Python):
def countOdd(l):
if l == list(): return 0 # base case, empty list means we're done
return l[0] % 2 + countOdd(l[1:]) # add 1 (or don't) depending on odd/even of element 0. recurse on the rest
x%2 is 1 for odds, 0 for evens. If you are uncomfortable with it or just don't understand it, use the following in place of the last line above:
thisElement = l[0]
restOfList = l[1:]
if thisElement % 2 == 0: currentElementOdd = 0
else: currentElementOdd = 1
return currentElementOdd + countOdd(restOfList)
PS - this is pretty recursive, see what your teacher says if you turn this in =P
>>> def countOdd(l):
... return fold(lambda x,y: x+(y&1),l,0)
...
>>> def fold(f,l,a):
... if l == list(): return a
... return fold(f,l[1:],f(a,l[0]))
All of the prior answers are subdividing the problem into subproblems of size 1 and size n-1. Several people noted that the recursive stack might easily blow out. This solution should keep the recursive stack size at O(log n):
def count_odd(series):
l = len(series) >> 1
if l < 1:
return series[0] & 1 if series else 0
else:
return count_odd(series[:l]) + count_odd(series[l:])
The goal of recursion is to divide the problem into smaller pieces, and apply the solution to the smaller pieces. In this case, we can check if the first number of the list (l[0]) is odd, then call the function again (this is the "recursion") with the rest of the list (l[1:]), adding our current result to the result of the recursion.
def count_odd(series):
if not series:
return 0
else:
left, right = series[0], series[1:]
return count_odd(right) + (1 if (left & 1) else 0)
Tail recursion
def count_odd(integers):
def iter_(lst, count):
return iter_(rest(lst), count + is_odd(first(lst))) if lst else count
return iter_(integers, 0)
def is_odd(integer):
"""Whether the `integer` is odd."""
return integer % 2 != 0 # or `return integer & 1`
def first(lst):
"""Get the first element from the `lst` list.
Return `None` if there are no elements.
"""
return lst[0] if lst else None
def rest(lst):
"""Return `lst` list without the first element."""
return lst[1:]
There is no tail-call optimization in Python, so the above version is purely educational.
The call could be visualize as:
count_odd([1,2,3]) # returns
iter_([1,2,3], 0) # could be replaced by; depth=1
iter_([2,3], 0 + is_odd(1)) if [1,2,3] else 0 # `bool([1,2,3])` is True in Python
iter_([2,3], 0 + True) # `True == 1` in Python
iter_([2,3], 1) # depth=2
iter_([3], 1 + is_odd(2)) if [2,3] else 1
iter_([3], 1 + False) # `False == 0` in Python
iter_([3], 1) # depth=3
iter_([], 1 + is_odd(3)) if [3] else 1
iter_([], 2) # depth=4
iter_(rest([]), 2 + is_odd(first([])) if [] else 2 # bool([]) is False in Python
2 # the answer
Simple trampolining
To avoid 'max recursion depth exceeded' errors for large arrays all tail calls in recursive functions can be wrapped in lambda: expressions; and special trampoline() function can be used to unwrap such expressions. It effectively converts recursion into iterating over a simple loop:
import functools
def trampoline(function):
"""Resolve delayed calls."""
#functools.wraps(function)
def wrapper(*args):
f = function(*args)
while callable(f):
f = f()
return f
return wrapper
def iter_(lst, count):
#NOTE: added `lambda:` before the tail call
return (lambda:iter_(rest(lst), count+is_odd(first(lst)))) if lst else count
#trampoline
def count_odd(integers):
return iter_(integers, 0)
Example:
count_odd([1,2,3])
iter_([1,2,3], 0) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([2,3], 0+is_odd(1)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([3], 1+is_odd(2)) # returns callable
lambda:iter_(rest(lst), count+is_odd(first(lst))) # f = f()
iter_([], 1+is_odd(3))
2 # callable(2) is False
I would write it like this:
def countOddNumbers(numbers):
sum = 0
for num in numbers:
if num%2!=0:
sum += numbers.count(num)
return sum
not sure if i got your question , but as above something similar:
def countOddNumbers(numbers):
count=0
for i in numbers:
if i%2!=0:
count+=1
return count
Generator can give quick result in one line code:
sum((x%2 for x in nums))

Categories

Resources