I have a very simple function which summarize the list elements without using sum function or looping technique. Here it is:
def find_sum(mylist):
def get_value(sublist, counter):
counter += sublist.pop()
if sublist:
get_value(sublist, counter)
else:
print counter # It will print correct result
return counter
my_sum = get_value(mylist, 0) # But my_sum is None
return my_sum
Why the emdedded function returns None?
Related
I need to allocate some values in 3 individual lists.
The values are generated on the fly but all included in the 0-6 range.
The point is that these values should be put in the three lists so that the average of each list does not differ so much from the others. The lists also need to be similar in length.
So the goal would be to progressively fill these lists to maintain, as much as possible, a uniform average value and size for all of them.
As I didn't found any built-in function to do this, I have implemented a code which keeps track of lists length and tries to keep them as close as possible in their average value. You can play with it and improve it to better fit your case.
class Data:
def __init__(self):
"""Init the three lists."""
self.a = []
self.b = []
self.c = []
#staticmethod
def get_average(data: list):
"""Get average value of a list."""
try:
return sum(data) / len(data)
except ZeroDivisionError:
return 0
def get_shortest(self):
"""Return list with the shortest length."""
shortest_length = min(len(self.a), len(self.b), len(self.c))
if len(self.a) == shortest_length:
return self.a
elif len(self.b) == shortest_length:
return self.b
else:
return self.c
def get_smallest(self):
"""Return list with the smallest average value."""
smallest_average = min(self.get_average(self.a), self.get_average(self.b), self.get_average(self.c))
if self.get_average(self.a) == smallest_average:
return self.a
elif self.get_average(self.b) == smallest_average:
return self.b
else:
return self.c
def get_highest(self):
"""Return list with the highest average value."""
highest_average = max(self.get_average(self.a), self.get_average(self.b), self.get_average(self.c))
if self.get_average(self.a) == highest_average:
return self.a
elif self.get_average(self.b) == highest_average:
return self.b
else:
return self.c
def add_number(self, num):
"""Add number to one of the lists."""
shortest = self.get_shortest()
smallest = self.get_smallest()
highest = self.get_highest()
# Lists must not differ by more than two elements
if len(smallest) - len(shortest) >= 2 or len(highest) - len(shortest) >= 2:
shortest.append(num)
else:
# Test if the number uppers the smallest average
initial_avg = self.get_average(smallest)
smallest.append(number)
final_avg = self.get_average(smallest)
if final_avg > initial_avg:
return
else:
smallest.pop()
# Test if the number lowers the highest average
initial_avg = self.get_average(highest)
highest.append(number)
final_avg = self.get_average(highest)
if final_avg < initial_avg:
return
else:
highest.pop()
# Last resort
shortest.append(num)
d = Data()
value = input("Add number: ")
while value != 'e':
try:
number = int(value)
except ValueError:
break
d.add_number(number)
print(f"List a: {d.a}, avg. {d.get_average(d.a)}")
print(f"List b: {d.b}, avg. {d.get_average(d.b)}")
print(f"List c: {d.c}, avg. {d.get_average(d.c)}")
value = input("Add number:")
So I have this class:
#!/usr/bin/python3
class MyClass(object):
def __init__(self, length):
self._list = length
def get(self, index):
try:
return self._list[index]
except IndexError:
return None
which takes in a list and returns a value, a list index I think. I am trying to get that value:
def my_function(a_list):
a_list = MyClass
for x in (10**p for p in range(1, 9)):
if a_list:
print(a_list)
def main():
length = my_function(MyClass([i for i in range(0, 543)]))
but I keep getting only the memory location of the list, I think this is supposed to return an int.
I am hoping this is a workable bit of code, but I am struggling, with the concept of passing an "object" to a class, it doesn't make any sense to me.
Here is a test I am supposed to use:
def test_large_list():
s_list = My_Class([i for i in xrange(0, 100000)])
assert len(s_list._list) == list_length(s_list)
Ok, Here is my full function that works, it is done, how od I do this so that the first line takes an argument
#!/usr/bin/python3
#def list_length(single_method_list): This is what I am supposed to work with
from single_method_list import SingleMethodList
def my_function(): # This is how I have done it and it works.
a_list = MyClass([i for i in range(0, 234589)])
for x in (10**p for p in range(1, 8)):
if a_list.get(x):
print("More than", x)
first = x
else:
print("Less than", x)
last = x
break
answer = False
while not answer:
result = (first + last)/2
result = int(round(result))
print(result)
if s_list.get(result):
first = result
print('first', result)
else:
last = result
print('last', result)
if s_list.get(result) and not s_list.get(result + 1):
answer = True
print(result + 1)
my_function()
I don't know what more I can give to explain where I am stuck, it is the OOP part of this that I don't know I need the same results here, just passing it to the function instead of creating it inside the function which I did in order to do the algorithm.
Well your class does something else.MyClass is designed to take a List at initialization, so the naming length is not a good idea.
The get() method of this class takes in a number and returns the element located at that particular index in the initialized self._list.
Your logic should be like:
def my_function(a_list):
a_list = MyClass(a_list)
...
def main():
length = my_function([i for i in range(0, 543)])
Just to clarify some misunderstanding that you might have.
Class does not return anything. It is a blueprint for creating objects.
What can return value is a method (function). For instance, if you want to write a method which returns length of some list:
def my_function(some_list):
return len(some_list)
Or in your case:
def my_function(a_list):
return len(a_list._list)
Note that you should not call your variables list. It's a built-in function in python which creates lists.
And as you can see there is another built-in function len in python which returns length of list, tuple, dictionary etc.
Hope this helps, although it's still a bit unclear what you're trying to achieve.
Why is it when executing this code, the final return is a None?
def evenNum(x):
for num in x:
if num%2==0:
print num
a = [1,2,3,4,5,6,7,8,9,10]
print evenNum(a)
How do i omit that None value?
Because you do not return any value in your function. If you want to have the list of even numbers you should do some thing like this:
def evenNum(x):
even_nums = []
for num in x:
if num%2==0:
even_nums.append(num)
print num
return even_nums
Your function does not return anything, or, in other words, it returns None. Replace:
print evenNum(a)
with:
evenNum(a)
to avoid None being printed.
evenNum - Its function returns no value, then the default is to return None
So I am working on comparing the iterative and recursive ways of finding fibonacci numbers. I wanted to pass them both into timeit, but am having trouble formatting my calls to timeit. Good someone give me a little guidance please? Thanks!
import timeit
def it_fib(n):
total = 0
while n > 0:
total += n
n -= 1
return total
def rec_fib(n):
if n == 0:
return 0
else:
return n + rec_fib(n-1)
#print (it_fib(10))
#print (rec_fib(10))
print timeit.timeit("it_fib(n)", number = 1000000)
print timeit.timeit("rec_fib(n)", number = 1000000)
timeit.timeit can take a function or a string. For script use, the function is usually more convenient:
print timeit.timeit(lambda: it_fib(10))
print timeit.timeit(lambda: rec_fib(10))
I am trying to append or add the sum of iterables through a range to an empty list. I was able to do it using a for loop:
list=[]
list_2=[]
def clique(n):
for i in range(n):
list.append(i)
list_2=sum(list)
print clique(4)
but everytime I try to do it within a function I get this error:
TypeError: range() integer end argument expected, got list.
the outputs is:
None
When you do print some_function(), the output is the return value of the function. If the function has no return statement, the return value is None by default. This is why print clique(4) prints None.
If you want print clique(4) to show the contents of list, then return list.
def clique(n):
for i in range(n):
list.append(i)
list_2=sum(list)
return list
try this:
list=[]
def clique(n):
for i in range(n):
list.append(i)
list_2=sum(list)
print 'list', list
print 'list_2', list_2
clique(4)