I want to add every nth number from list recursively, but NOT the first number, so lets say I have a list [1, 2, 3, 4, 5, 6] and I want to add every 2nd number, so that would mean I need to add 2 + 4 + 6 but if I want to add every 3rd number, then it should add 3 + 6.
So right now I have this much, I want to add every 2nd number so that means I want to add 2, 4 and 6, but I can't seem to figure out why it doesn't work, what should I do differently?
def getsum(numbers):
if len(piece)==0:
return 0
else:
return getsum(numbers[2:]) + numbers[0]
print getSum([1, 2, 3, 4, 5, 6])
You can pick out the nth number, then recursively slice off everything after that when you call the function again
def get_sum(numbers, n):
if len(numbers) < n:
return 0
return numbers[n-1] + get_sum(numbers[n:], n)
For example with n = 2 and n = 3 respectively
>>> get_sum([1, 2, 3, 4, 5, 6], 2) # 2 + 4 + 6
12
>>> get_sum([1, 2, 3, 4, 5, 6], 3) # 3 + 6
9
Related
The problem statement is:
Design and implement an algorithm that displays the elements of a list
by interleaving an element from the beginning and an element from the
end.
For example, input:
1 2 3 4 5 6 7 8
Output :
1 8 2 7 3 6 4 5
This is what I tried, but I don't know what happen with elements 7 and 8:
lista = [1, 2, 3, 4, 5, 6, 7, 8]
for i in range(len(lista)):
lista.insert(2*i-1,lista.pop())
print("The list after shift is : " + str(lista))
# output:
# The list after shift is : [1, 7, 2, 8, 3, 6, 4, 5]
The only error in you code, is that range(len(lista)) starts from 0, not from 1. By starting from zero, in the first iteration 2*i-1 will be 2*0-1 = -1, and hence lista.insert(-1,lista.pop()), which means inserting at the very end of the list (that is what index -1 means in python).
To fix your code, you just need to start the range from 1. Actually, you are iterating too much, you can have your range just from 1 to the half of your list, like this:
lista = [1, 2, 3, 4, 5, 6, 7, 8]
for i in range(1, len(lista)//2):
lista.insert(2*i-1,lista.pop())
print("The list after shift is : " + str(lista))
# output:
# The list after shift is : [1, 8, 2, 7, 3, 6, 4, 5]
When you become more familiarized with the language, you will see that this can be accomplished much more easily.
For example, you can use the python slice syntax to achieve your goal. You slice from beginning to half , and from end to half (step of -1), then zip then together and flat.
[i for z in zip(lista[:4],lista[:-5:-1]) for i in z]
# [1, 8, 2, 7, 3, 6, 4, 5]
Another option:
import math
lista = [1, 2, 3, 4, 5, 6, 7, 8]
ans = []
for i in range(math.floor(len(lista)/2)):
ans.append(lista[i])
ans.append(lista[-i-1])
if (len(lista) % 2) != 0:
ans.append(lista(math.ceil(len(lista)/2)))
print(ans)
Technically speaking, I'd say it's two off-by-one errors (or one off-by-one error, but from -1 to +1, you'll see what I mean in the second paragraph). The first one is that you're subtracting 1 when you shouldn't. In the case when i = 0 (remember that range(n) goes from 0 to n-1), the insert position is being evaluated as 2*0-1 = (2*0)-1 = 0-1= -1 (for insert() method, that's the last position of the original list, pushing what was there forward, so it'll be the penultimate position of the NEW list).
But, when you remove the -1, the output becomes 8 1 7 2 6 3 5 4, which is close to what you want, but not quite right. What's missing is that the elements inserted should be at positions 1, 3, 5, 7, and not 0, 2, 4, 6. So, you'll actually need to add 1.
So, the shortest change to fix your code is to change lista.insert(2*i-1,lista.pop()) to lista.insert(2*i+1,lista.pop()).
Notice: if you put a print inside for, you'll realize that, after changing half the elements, the output is already right. That's because when len(lista) is 8, and you do lista.insert(x, lista.pop()) where x is bigger than 8, basically you're removing the last element (pop) and adding it at the end, so, nothing changes. Hence, you could also change range(len(lista)) to range(len(lista)//2). Test if it'll work when len(lista) is odd
For example, let's say that I have a range of "10-1," how can I express this to say [1 2 3 4 5 6 7 8 9 10]?
You can use split to read the start and end, use int to convert them into integers, and then use range to return a desired list.
def range_to_list(s):
end, start = map(int, s.split('-'))
return list(range(start, end + 1))
print(range_to_list('10-1')) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Depending on your goal, list might not be necessary.
List:
x = [1, 6, 2, 7, 1, 6, 1]
len(x)
> 7
How would I split the list for the first 3 and last 3, thus value 7 is left alone using list slicing methods?
Output
x[0:2,4:6] #<-- This doesn't work
> [1, 6, 2, 1, 6, 1] #<-- Expected output
Meeting OP requeriment: "Is there a way to just keep it same brackets? x[...,...] similar to this one? " (not just using x[:3]+x[-3:]):
Use numpy.delete together with numpy.r_. Specify which first number of elements n1 and which last number of elements n2 you want to keep this way
import numpy as np
x = [1, 6, 2, 7, 1, 6, 1]
n1 = 3 # Keep first n1 elements
n2 = 3 # Keep last n2 elements
print(list(np.delete(x,(np.r_[n1:len(x)-n2])))) # [1 6 2 1 6 1]
You could do: x[0:3]+x[4:7] or x[:3]+x[-3:]. The second one gets the first 3 elements from the last and the first three elements from the right.
numbers=[i**3 for i in range (10) if i**3%3==1]
print(numbers)
#gets 1,64,343
Why is 1, 64, 343 the answer?
This is equivalent to the code:
for i in range(10):
if (i*i*i) % 3 == 1:
numbers.append(i*i*i)
print (numbers)
You are checking if the remainder obtained when the cube of a number from 1 to 10 is divided by 3 is equal to 1. If it is, you are adding it to a list and printing it.
The meaning of **
ex: 2**3= 2*2*2 #this means 2 to the power 3 = 8
The meaning of %
ex: 5%2= 1 #the sign means module, that means the remaining value after divide 5 by 2, it is one.
in your way, the correct path to write the for each is
for i in range(0,10):
value = i**3
if(value%3 == 1):
print("the value is {0}".format(value))
so the result is :
the value is 1
the value is 64
the value is 343
bit explanation inside the for loop
first get the i = 0, at this point value = 0*0*0 = 0, then value%3=0
then get the i=1, at this point value = 1*1*1 = 1 ,the 'value%3' means 1%3 = 1, so the answer i 1
.... like this see about other conditions also. hope this will help to you.
first i is in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
then if (i*i*i) rem 3 is equal to 1
it selects (i*i*i)
and for [1,4,7]: (1*1*1)%3==1, (4*4*4)%3==1 and (7*7*7)%3==1:
1*1*1=1 and 1/3=0 :remainder=1
4*4*4=64 and 64/3=21 :remainder=1
7*7*7=343 and 343/3=114 :remainder=1
so the output is:
[1*1*1, 4*4*4, 7*7*7] which is [1, 64, 343]
your code:
numbers=[i**3 for i in range (10) if i**3%3==1]
print(numbers)
and this code:
numbers=[]
for i in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
if (i*i*i) % 3 == 1:
numbers.append(i*i*i)
print(numbers)
output this:
[1, 64, 343]
I have some weird numbers such as 19 or 23. These two will need to be separated into 5 lists, such that the sum of the 5 lists will be 19. In other words, 3.8 in each list as 19/5 = 3.8. However the issue is that I can't have decimals, I want rounded numbers. Is there any way that it would round the numbers accordingly, placing 4, 4, 3, 4, 4 into the lists rather than 3.8 five times?
Even more, some aren't separated into 5 different numbers. Some might be something like 77/12, thus being separated into 12 diff. lists with either the number 6 or 7 in each, that ends up adding to 77.
Any idea how I could approach this problem?
Thanks!
def split(number, length):
div, mod = divmod(number, length)
return [div+1]*mod + [div]*(length-mod)
>>> split(19, 5)
[4, 4, 4, 4, 3]
>>> split(23, 4)
[6, 6, 6, 5]
Original version:
def split(number, length):
result = [number//length]*length
for i in range(number%length):
result[i] += 1
return result
here you go.
def roundto(number,items):
start = [1 for i in xrange(items)]
reached = False
while not reached:
for i in xrange(len(start)):
start[i] += 1
if sum(start) == number:
return start
print roundto(19,5)
>>>
[4, 4, 4, 4, 3]