Python loops with break/continue - python

Given a set of integers numbers = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9] containing at least two zeros. Print the sum of numbers from the given set located between the last two zeros (if the last zeros are in a row, then print 0).
My attempt:
numbers = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9]
index_of_first_zero = 0
i = 0
while i < len(numbers):
if numbers[i] == 0:
index_first_zero = 1
break
i += 1
index_of_last_zero = len(numbers) - 1
i = len(numbers) - 1
while i >= 0:
if numbers[i] == 0:
index_of_last_zero = i
break
i -= 1
summa = 0
while i in range(index_of_first_zero+1, index_of_last_zero):
summa += numbers[i]
print("Summa =", summa)
But unput is Summa = 0
Can you help me please?

It's much easier to reverse the list and look for the first two zeros.
>>> numbers = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9]
>>> numbers_rev = reversed(numbers)
>>> sum_ = 0
>>>
>>> for x in numbers_rev:
... if x == 0:
... break
>>>
>>> for x in numbers_rev:
... if x == 0:
... break
... sum_ += x
>>>
>>> sum_
2
Alternative:
numbers = [10, 0, 11, 5, 3, 0, 6, 0, 2, 5, 6, 0, 6, 9]
numbers_rev = numbers[::-1]
sum_ = 0
for x in numbers_rev[numbers_rev.index(0)+1:]:
if x == 0:
break
sum_ += x

This should do the trick...
a = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9]
i1 = a[::-1].index(0)
i2 = a[::-1].index(0,i1+1)
print("Summa =",sum(a[len(a)-i2:len(a)-i1]))

I hope this makes it clear :)
#take your original list
numbers = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9]
#reverse the list
numbes = numbers.reverse()
#make clear that the first zero has not been encountered
encountered_zero = False
#set the temporary sum to 0
cur_sum = 0
#for every number in your list
for number in numbers:
#if it's a zero, and you haven't passed any yet
if number == 0 and not encountered_zero:
#mark it
encountered_zero = True
#skip the rest of the iteration
continue
#if you have already encountered a zero
if encountered_zero == True:
#add every number to the sum
cur_sum += number
#if you encounter another zero
if encountered_zero == True and number == 0:
#break out of the loop, you're done
break
#here you have your answer
summa = cur_sum
print("Summa =", summa)

There are a few mistakes in your program...
One mistake in your program is that in the final part you're telling the script: "While the variable i is in the iterator range do [...]"
However, you should put a for loop there, not a while, changing it to:
summa = 0
for i in range(index_of_first_zero+1, index_of_last_zero):
summa += numbers[i]
print("Summa = ", summa)
Now that part of the program should work properly, because i in the for loop will be replaced with the values in the range iterator.
Instead, with the while, i takes index_of_last_zero as value, so it will never be in the range iterator.
However, the second error is a logical one: you have to sum the numbers between the last two zeros, not between the first and the last one, so the best thing to do is to reverse the list as other users already answered, so the entire program has to change:
original_list = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9]
reversed_list = reversed(original_list)
my_sum = 0
for num in reversed_list:
if num == 0:
# it breaks here because it found the first zero,
# and then it will continue the cycle from the next element
break
# Now it won't loop again from the beginning, but from where it broke before.
for num in reversed_list:
if num == 0:
break
my_sum += num
print(my_sum) # -> 2
This program will work, thanks to #timgeb, and works with reversed() which is a built-in function that returns an Iterator object.
Here will be clarified to you what is an Iterator and how to work with it.
Anyway, I'll put here another solution that won't use that function.
original_list = [10, 0, 11, 5, 3, 0, 6, 0, 2, 0, 6, 9]
reversed_list = [] # we'll create it manually
my_sum = 0
# let's create here the reversed_list
for i in range(len(original_list) - 1, 0, -1):
reversed_list.append(original_list[i])
while i < len(reversed_list):
if reversed_list[i] == 0:
# it breaks here because it found the first zero,
# and we store the index of the first zero.
index_first_zero = i
break
i += 1
# Now it won't loop again from the beginning, but from where it broke before.
for i in range(index_first_zero, len(reversed_list)):
if reversed_list[i] == 0:
break
my_sum += reversed_list[i]
print(my_sum) # -> 2

Related

Adding condition in list in python

I don't know how to add extra conditions to this code.
(Only using randint)
For example with list [1, 2, 3, 4, 0] I need to generate random number except the last one (covered in my code) but the next condition is, it can not choose an index number which has a value of 0. So for list [3, 3, 0, 3, 3, 7] it can only consider indexes 0,1,3,4 (not 2 and 5 because I can not include the last number and index with value 0).
My code so far:
import random
our = [2, 3, 4, 0]
random_index = random.randint(0, len(our)-2)
random_number = our[random_index]
print(random_number)
I will be very glad for any help.
You can create a second list that stores the valid index values.
import random
our = [3, 3, 0, 3, 3, 7]
index = []
for i in range(0, len(our)-1) :
if our[i] != 0 :
index.append(i)
# index: [0, 1, 3, 4]
random_index = random.choice(index)
EDIT: You can perform a sanity check for a non-zero value being present.
The any() function returns True if any element of an iterable is True. 0 is treated as False and all non-zero numbers are True.
valid_index = any(our[:-1])
if valid_index:
index = []
for i in range(0, len(our)-1) :
if our[i] != 0 :
index.append(i)
You can use a while loop to check if the number equals 0 or not.
import random
our = [3, 6, 2, 0, 3, 0, 5]
random_number = 0
while random_number == 0:
random_index = random.randint(0, len(our)-2)
random_number = our[random_index]
print(random_number)

Modifying an array in python using nested loops

I have an array, p=(1,2,4,5,7,10...) and I would like to input a 0 in where the array deviates from f=(1,2,3,4,5,6...). I have tried using nested for loops but I can't work out how to make the desired output=(1,2,0,4,5,0,7,0,0,10...) using python.
This is all I have really got so far, but it iterates for p[0] with all the elements of f before moving on to p[1] and I don't know how to prevent this:
for x in f:
for y in p:
if x==y:
print(x)
break
else:
print('0')
Thank you!
I'd suggest to make p a set so that checking membership is fast:
>>> p = (1,2,4,5,7,10)
>>> p_set = set(p)
>>> tuple([i if i in p_set else 0 for i in range(11)])
(0, 1, 2, 0, 4, 5, 0, 7, 0, 0, 10)
code:
p =(1,2,4,5,7,10)
f =tuple(range(1,11))
for x in f:
for y in p:
if x == y:
print(x)
break
else:
print('0')
result:
1
2
0
4
5
0
7
0
0
10
You don't need a nested loop, just iterate through the full numbers' array and insert a zero. Example
p = [1,2,3,4,5,6,7,8,9,10,11,12,13,14, 15]
f = [1,2,4,5,6,7,10,14,15]
for index,i in enumerate(p):
if i == f[index]:
pass
else:
f.insert(index, 0)
Result
[1, 2, 0, 4, 5, 6, 7, 0, 0, 10, 0, 0, 0, 14, 15]

Use a while loop to find sum of list until negative number or end of list appears

I am supposed to use a while loop to find the sum of a list until it reaches a negative number or until it reaches the end of the list. Here are example lists:
v = [ 10, 12, 3, -5, 5, 6 ]
v = [ 0, 10, 3, 6, 5, 1 ]
The output total sum for both lists should be 25. Here is my code:
result = 0
i = 0
for num in v:
while num >= 0:
result += num
i += 1
print(result)
For both of the lists, my output is just a blank infinite loop. The code I provided was the code I thought made the most sense.
You should use OR conditions with a single while loop, like so:
v = [10, 12, 3, -5, 5, 6]
v = [0, 10, 3, 6, 5, 1]
result = 0
i = 0
# while the sum is still at or above 0 and the list isn't out of bounds
while v[i] >= 0 and i < len(v):
num = v[i]
result += num
i += 1
print(result)
This enables you to avoid break statements, which are generally bad coding practice.
Use if, not while, and break to terminate the loop early. Also, you do not need i.
v = [ 10, 12, 3, -5, 5, 6 ]
# v = [ 0, 10, 3, 6, 5, 1 ]
sum_non_negatives = 0
for num in v:
if num < 0:
break
sum_non_negatives += num
print(sum_non_negatives)
Using only while (not for):
result = 0
i = 0
while i<len(v) and v[i] >= 0:
result += v[i]
i += 1
print(result)

Adding numbers in a list except a specific number and the following number

I am new to programming and I am trying to add up all the numbers in a given list except for the the number 13 and any number following the number 13. the problem that I am having is that if 13 is on the end of the list it won't add the first number. Any help would be appreciated. The code I have is as follows:
def sum13(nums):
total = 0
for i in range(len(nums)):
if nums[i] == 13 or nums[i-1] == 13:
total += 0
else:
total += nums[i]
return total
def main():
print sum13([1, 2, 2, 1, 13])
print sum13([1, 2, 13, 2, 1, 13])
main()
The two examples should result in 6 and 4 however it results in 5 and 3 because it isn't adding the 1 at the beginning.
In Python, an index of -1 means the last item in a list. So, in your code, when i is 0 (the first number), it will not count it because the last item in the list is 13.
You can fix this with a simple check that i > 1 on that condition:
if nums[i] == 13 or (i > 0 and nums[i - 1] == 13):
Also for what it's worth, because we all love one-liners, here's an equivalent function in a line:
return sum(num for i, num in enumerate(nums) if num != 13 and (i == 0 or nums[i - 1] != 13))
My proposition:
def sum13(numbers):
total = 0
skip = False
for i, number in enumerate(numbers):
if number == 13:
skip = True
continue
if skip:
skip = False
continue
total += number
return total
def test():
cases = [
([13, 1, 1], 1),
([13, 1, 5, 13], 5),
([1, 13, 5, 1], 2),
([1, 2, 2, 1, 13], 6),
([1, 2, 13, 2, 1, 13], 4),
]
for case in cases:
assert sum13(case[0]) == case[1]
test()
Read about enumerate if it's new for you:
https://docs.python.org/3.4/library/functions.html#enumerate

Python making list

I'm a super n00b in python.
I have been struggling with finding proper solution.
Here is the list, L = [0, 0, 0, 3, 4, 5, 6, 0, 0, 0, 0, 11, 12, 13, 14, 0, 0, 0, 18, 19, 20], and each of the items refers to location in the list.
I wanted to make list from the upper list, showing smaller lists inside the list, and each of the elements represents starting location of the series, end of the series and number of elements. This should be [[3, 6, 4], [11, 14, 4], [18, 20, 3]]. How could I write code for this? Following is what I have done so far.
target = []
target.append([])
target.append([])
target.append([])
L = [0,0,0,0,4,5,6,7,8,9,0,0,0,13,14,15,0,0,0,19,20,21]
for i in L :
if i == 0 :
L.remove(i)
continue
elif i != 0 :
startpoint = i
i = i * i
while i != 0 :
i += 1
continue
else :
j = i
endpoint = i - 1
break
target[0].append(startpoint)
target[1].append(endpoint)
target[2].append(j)
About your code one mistake is that in following while :
while i != 0 :
i += 1
You must not increase i you need to increase the index of elements not itself!then continue to appending when you find a none zero element!
But as a more pythonic way You can use itertools.groupby with a list comprehension :
>>> from itertools import groupby
>>> [[i[0],i[-1],len(i)] for i in [list(g) for _,g in groupby(L,key=lambda x:x!=0)]if i[0]!=0]
[[3, 6, 4], [11, 14, 4], [18, 20, 3]]
Note that groupby returns the grouped elements as a generator (g) and when you want to loop over it you dont need to convert it to list but in this case as we need the length we must convert to list till we can use len function.
Here's a version based on your attempt:
L=[0,0,0,3,4,5,6,0,0,0,0,11,12,13,14,0,0,0,18,19,20]
target = []
i = 0
while i < len(L):
if L[i] == 0 :
i += 1
continue
start = i
while i < len(L) and L[i] != 0:
i += 1
target.append((L[start],L[i-1],i-start))

Categories