Summation of values in nested lists - python

I have encountered a problem where a return gives None back, though the variable had a value just a single line of code before.
mylist = [[7]]
def sumcalc(the_list,n):
s = n
for x,y in enumerate(the_list):
if type(y) == list:
sumcalc(y,s)
elif type(y) == int:
s += y
if x < len(the_list)-1:
sumcalc(the_list[x+1], s)
else:
print (s)
return s
print(sumcalc(mylist,0))
The print command in the second to last line gives me 7, as expected. But the return is None. Any help on this would be appreciated :)

If you are writing a recursive function. You must put return key word before recursive call.
mylist = [[7]]
def sumcalc(the_list,n):
s = n
for x,y in enumerate(the_list):
if type(y) == list:
return sumcalc(y,s)
elif type(y) == int:
s += y
if x < len(the_list)-1:
sumcalc(the_list[x+1], s)
else:
print (s)
return s
print(sumcalc(mylist,0))

sumcalc() doesn't do anything on its own; you need to use the return value. Beyond this, the index checking is unecessary, as the return could simply be placed after the loop. Here is a simpler way of writing the nested sum code.
def nested_sum(x):
if type(x)==int:
return x
if type(x)==list:
return sum(
nested_sum(item)
for item in x
)

Related

Loop. Why it can see only 10 from whole list?

def new_list(lst):
for i in lst:
if i%10 == 0:
return i
else:
return False
print(new_list([10, 20.0, 25, 30, 40, 98]))
i want to see all numbers from the list that can be divided into 10
Calling return in a function ends execution of the function. So either way, the your function will stop running after the first iteration in your for loop. I don't know what you are expecting for output, but in your function you can instead append the items to a list and return the list at the end:
def new_list(lst):
result_list = []
for i in lst:
if i%10 == 0:
result_list.append(i)
return result_list
This can also be done with a list comprehension:
def new_list(lst):
return [x for x in lst if x % 10 == 0]

Infinite while loop implementing Remove function using Open Addressing on Hash Table - Python

I am trying to implement the remove function with linear probing on a hash table.
I am having a problem with that, when I try to call the function remove it enter an infinite loop.
How can I fix that problem??
I have written the function taking the pseudocode:
remove(t, k):
z = 0
repeat
x = hash_function (k, z)
if hash_table[x] == k:
hash_table[x] = deleted return x
z = z+1
until hash_table[x] == NIL or z == m
return NIL
This is the code into a class:
class lin_prob:
def __init__(self, table_size):
self.hash_table = [None]*table_size
self.n_prime = 109169
self.a = random.randint(2, self.prime-1)
self.b = random.randint(2, self.prime-1)
self.n_keys = 0
def remove(self, k):
z = 0
while self.hash_table[x] != None or z < len (hash_table):
x = self.hash_function(k)
if self.hash_table[x] == k:
self.hash_table[x] = "deleted"
return x
else :
z = z+1
return "NIL"
def hash_function(self, k):
return ((self.a*k + self.b) % self.prime_number) % len(self.hash_table)
def len(self):
return self.n_keys
If you want to negate the until condition to create a while condition, you must change the or to an and:
while self.hash_table[x] != None and z < len (hash_table):
...
Also, you code cannot work because x is unknown in your remove method.
The problem arises with the condition you put into the while loop
while self.hash_table[x] != None and z < len (hash_table):
because the negation of equal == is not equal !=. I believe it will fix your problem.

remove negative element from nested list and square the list without using loop

Input: testlist = [[1,2,3,-1],2,3,[3,-4,1,3],-1,-3]
Requirement:
remove elements less than zero
then square the elements without using any loop
output :
[[1,4,9],4,9,[9,1,9]]
def testlist(f, l):
def listelement(inside):
return testlist(f, inside) if type(inside) is list else f(inside)
return list(map(listelement, l))
def square(x):
return x * x
def square_list(l):
return testlist(square, l)
You could think about the problem recursively:
If the list is empty, return an empty ist
If it isn't, for the first item of the list:
If it's a negative number, omit it
If it's a non-negative number, square it
If it's a list, apply the function on it.
Return a list that's a concatenation of the element from #1 and the function applied to the rest of the list.
Or, in python:
def func(l):
if len(l) == 0:
return []
item = l[0]
if isinstance(item, list):
result = [func(item)]
elif item >= 0:
result = [item**2]
else:
result = []
return result + func(l[1:])
Instead of having two separate functions, you can do the squaring and the checking for positive in the same function.
To handle not looping we can use recursion. Since we are already using recursion, we can handle lists with the same recursive function.
test_list = [[1,2,3,-1],2,3,[3,-4,1,3],-1,-3]
def positive_square_list(lst, index):
if index < len(lst):
if type(lst[index]) == list:
positive_square_list(lst[index], 0)
index += 1
if lst[index] < 0:
lst.pop(index)
index -= 1
if index == len(lst):
return lst
else:
return positive_square_list(lst, index+1)
lst[index] = lst[index] ** 2
return positive_square_list(lst, index+1)
return lst
output = positive_square_list(test_list, 0)
The variable output will have the values: [[1,4,9],4,9,[9,1,9]]

I am trying to make a function which return max from nested list?

I wrote this and its working fine with everything but when I have an empty list
in a given list(given_list=[[],1,2,3]) it saying index is out of range. Any help?
def r_max (given_list):
largest = given_list[0]
while type(largest) == type([]):
largest = largest[0]
for element in given_list:
if type(element) == type([]):
max_of_elem = r_max(element)
if largest < max_of_elem:
largest = max_of_elem
else: # element is not a list
if largest < element:
largest = element
return largest
You are assuming given_list has at least 1 element which is incorrect.
To avoid index out of range, you may add
if (len(given_list) == 0)
return None
to the beginning of your function.
that error indicates your index is out of range, which is the case with the first element of your example. The solution is not to iterate over lists of length zero:
def r_max (given_list):
largest = given_list[0]
while type(largest) == type([]):
largest = largest[0]
for element in given_list:
if type(element) == type([]):
# If the list is empty, skip
if(len(elemnt) == 0)
next
max_of_elem = r_max(element)
if largest < max_of_elem:
largest = max_of_elem
else: # element is not a list
if largest < element:
largest = element
return larges
while your at it, you might want to assert len(given_list)>0 or something equivalent.
If the nesting is arbitrarily deep, you first need recursion to untangle it:
def items(x):
if isinstance(x, list):
for it in x:
for y in items(it): yield y
else: yield x
Now, max(items(whatever)) will work fine.
In recent releases of Python 3 you can make this more elegant by changing
for it in x:
for y in items(x): yield y
into:
for it in x: yield from it
If you're confident that there will only be one level of nesting in there, you could do something like
def r_max(lst):
new_lst = []
for i in lst:
try:
new_lst.extend(i)
except TypeError:
new_lst + [i]
return max(new_lst)
But I'm not in love with that solution - but it might inspire you to come up with something nicer.
Two things I'd like to highlight about this solution, in contrast to yours:
All the type-checking you're doing (type(largest) == type([]), etc.) isn't considered idiomatic Python. It works, but one of the key points of Python is that it promotes duck typing/EAFP, which means that you should be more concerned with what an object can do (as opposed to what type it is), and that you should just try stuff and recover as opposed to figuring out if you can do it.
Python has a perfectly good "find the largest number in a list" function - max. If you can make your input a non-nested list, then max does the rest for you.
This will find the maximum in a list which contains nested lists and ignore string instances.
A = [2, 4, 6, 8, [[11, 585, "tu"], 100, [9, 7]], 5, 3, "ccc", 1]
def M(L):
# If list is empty, return nothing
if len(L) == 0:
return
# If the list size is one, it could be one element or a list
if len(L) == 1:
# If it's a list, get the maximum out of it
if isinstance(L[0], list):
return M(L[0])
# If it's a string, ignore it
if isinstance(L[0], str):
return
# Else return the value
else:
return L[0]
# If the list has more elements, find the maximum
else:
return max(M(L[:1]), M(L[1:]))
print A
print M(A)
Padmal's BLOG
I assume that the max element of an empty list is negative infinity.
This assumption will deal with the cases like [], [1,2,[],5,4,[]]
def find_max(L):
if len(L) == 0:
return float("-inf")
elif len(L) == 1:
if isinstance(L[0], list):
return find_max(L[0])
else:
return L[0]
elif len(L) == 2:
if isinstance(L[0], list):
firstMax = find_max(L[0])
else:
firstMax = L[0]
if isinstance(L[1], list):
lastMax = find_max(L[1])
else:
lastMax = L[1]
if firstMax > lastMax:
return firstMax
else:
return lastMax
else:
if isinstance(L[0], list):
firstMax = find_max(L[0])
lastMax = find_max(L[1:])
if firstMax > lastMax:
return firstMax
else:
return lastMax
else:
lastMax = find_max(L[1:])
if L[0] > lastMax:
return L[0]
else:
return lastMax

How to add a counter to a recursive function? [Python]

The program has to replace two numbers within the list with a number that is also given in the parameters. I can't change the parameters, but I can create other functions also. In addition I must use recursion. So far I figured out how to do the replacement with recursion, but I'm confused about the count. Every time I try I cant seem to only replace the first two occurrences of 'x' with 'y', instead I always get to replace every 'x' with 'y'.
EDIT: And I can't use global variables.
def replaceFirstTwo(x,y,lst):
if lst == []:
return []
else:
if lst[0] == x:
return [y] + replaceFirstTwo(x,y,lst[1:])
else:
return [lst[0]]+ replaceFirstTwo(x,y,lst[1:])
A correct outcome should look like this :
replaceFirstTwo(1,2,[5,1,2,3,1,1])
[5, 2, 2, 3, 2, 1]
If x is only ever going to be positive then you can use, the negative version to signify that it is the second time that you are running the function. Before changing x to something to signify do nothing.
I have modified your function so it does this, however it will not work with negative values of x as the abs(x) will make it positive.
def replaceFirstTwo(x,y,lst):
if lst == []:
return []
else:
if x is not None:
if lst[0] == abs(x):
if x > -1:
x = -x
else:
x = None
return [y] + replaceFirstTwo(x,y,lst[1:])
else:
return [lst[0]]+ replaceFirstTwo(x,y,lst[1:])
else:
return [lst[0]]+ replaceFirstTwo(x,y,lst[1:])
Here's an alternative using an inner function, which has no restrictions such as the accepted solution:
def replaceFirstTwo(x, y, lst):
def sub(lst, res, count):
if lst:
e = lst[0]
if e == x and count < 2:
return sub(lst[1:], res+[y], count + 1)
else:
return sub(lst[1:], res+[e], count)
else:
return res
return sub(lst, [], 0)

Categories

Resources