Essentially my code looks like this
for i in range(10):
print(i)
if i == 8:
i -=1
That code prints 0 through 10 as normal instead of printing 8 twice. Is there any way to get around that?
Use this custom generator:
def same_number_iterator(last, same_number_twice):
i = 0
while i < last:
yield i
if i in same_number_twice:
yield i
i += 1
for i in same_number_iterator(10, same_number_twice=[8]):
print(i)
Output:
0
1
2
3
4
5
6
7
8
8
9
The solution by Aviv works for the problem you described. However, since the title says "Is it possible to iterate over the same number twice?" maybe what you want to know is how to repeat a certain iteration given a condition. If that's the case, you could simply do this:
repeated = False
i = 0
while i<10:
print(i)
if i == 8 and not repeated:
repeated = True
else:
i += 1
A simple thing that you can do is have an inner for loop, that does either 1 or 2 iterations depending on the value of i.
for i in range(10):
for _ in range(2 if i == 8 else 1):
print(i)
Related
So I am new to recursion and I am trying to make a program where you can enter a list and python tests each integer (lets say 9 for example) and sees if the integer following it is doubled. So if I entered a list of 2 4 8 16 32, would return 4, and -5 -10 0 6 12 9 36, would return 2 because -5 followed by -10 is one and 6 followed by 12 is the second. This is the code I have so far. I feel like I am very close. but just a few thing stand in my way. Any help would be great!
L = []
def countDouble(L):
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
print(y[1])
print(y[0])
count = 0
y[0] += y[0]
# unsure of how to multiple y[0] by 2
if y[0]*2 == y[1]:
count += 1
else:
count += 0
#how would I traverse through the rest of the entered list using recursion?
print(count)
countDouble(L)
If you want/need to solve it using recursion, the following will do the trick:
def count_sequential_doubles(li, count=0):
return count_sequential_doubles(li[1:], count + int(li[0] * 2 == li[1])) if len(li) > 1 else count
I would suggest this recursive way:
def countDouble(L):
count = 0
if len(L) == 1:
return count
else:
if int(L[0])*2 == int(L[1]):
count += 1
return count + countDouble(L[1:])
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
count = countDouble(y)
print(count)
I urge you to read the entire answer, but in case you are not interested in tips, notes and the process of finding the solution, here are two solutions:
solution using recursion (not recommended):
x = input()
y = x.split(' ')
count = 0
def countDouble(i):
if(i+1 == len(y)):
return 'recursion ends here when'
if(int(y[i])*2==int(y[i+1])):
count += 1
countDouble(i+1)
countDouble(0)
print(count)
this solution just imitates a while loop:
solution using a while loop (recommended):
x = input()
y = x.split(' ')
count = 0
i = 0
while(i < len(y) - 1):
if(int(y[i]) * 2 == int(y[i+1])):
count += 1
i += 1
print(count)
Before I continue, here are a few tips and notes: (some of them will only make sense after)
I assume the 14 in your example is a typo
I didn't put the code in a function because it's not needed, but you can change it easily.
In your code, you are passing L as a parameter to the countDouble() function, but you don't use it. if you don't need a parameter don't pass it.
when splitting the input, the values of the list are still strings. so you have to invert them to integers (for instance, you can do that with the int() 'function') before comparing their values - otherwise multiplying by 2 will just repeat the string. for example: '13'*2 is the string '1313'
I don't know why you why you added y[0] to itself in line 9, but based on the code that comes after this would yield incorrect results, you don't need to change the elements in order to get their value multiplied by 2.
notice that in the else block, nothing has changed. adding 0 to the count doesn't change it. so you can remove the else block entirely
While it's possible to solve the problem in recursion, there's something else designed for these kind of problems: loops.
The problem is essentially repeating a simple check for every element of a list.
This is how I would arrive to a solution
so we want to run the following 'code':
if(y[0]*2 == y[1]):
count += 1
if(y[1]*2 == y[2]):
count += 1
if(y[2]*2 == y[3]):
count += 1
...
of course the computer doesn't understand what "..." means, but it gives us an idea to the pattern in the code. now we can do the following:
divide the extended 'code' into similar sections.
identify the variables in the pattern - the values that change between sections
find the starting values of all variables
find a pattern in the changes of each variable
find a breaking point, a condition on one of the variables that tells us we have reached the last repeating section.
here are the steps in this specific problem:
the sections are the if statements
the variables are the indexes of the elements in y we compare
the first index starts at 0 and the second at 1
both indexes increase by one after each if-statement
when the second index is bigger then the last index of y then we already checked all the elements and we can stop
so all is left is to set the needed variables, have a while loop with the breaking condition we found, and in the while loop have the general case of the repeating sections and then the changing of the variables.
so:
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
count = 0
# setting the starting values of the variables
index1 = 0
index2 = 1
# creating a loop with the breaking condition
while(index2 < len(y)):
# the general case of the repeated code:
if(int(y[index1]) * 2 == int(y[index2])):
count += 1
# changing the variables for the next loop
index1 += 1
index2 += 1
print(count)
We see that the index2 is just index1 + 1 at all time. so we can replace it like that:
x = input(f'Enter a list of numbers separated by a space: ')
y = (x.split(' '))
count = 0
index1 = 0
while(index1 + 1 < len(y)):
if(int(y[index1]) * 2 == int(y[index1 + 1])):
count += 1
index1 += 1
print(count)
Note: You can use a for loop similarly to the while loop
So in summary, you can use recursion to solve the problem, but the recursion would just be imitating the process of a loop:
in each call, the breaking condition will be checked, the repeated code would run and the variables/parameters would change.
Hope you find this answer useful :)
Final edit: OP edited his example so my other code didnt apply
Some good questions people are asking, but in the spirit of helping, here's a recursive function that returns the count of all doubles.
def get_doubles_count_with_recursion(a_list, count, previous=None):
while a_list:
try:
first = previous if previous else a_list.pop(0)
next_item = a_list.pop(0)
except IndexError:
return count
if next_item / 2 == first:
count += 1
return get_doubles_count_with_recursion(a_list, count, next_item)
return count
a_list = [1, 3, 5, 10, 11, 14, 28, 56, 88, 116, 232, 464, 500]
doubles = get_doubles_count_with_recursion(a_list, 0)
print(doubles == 5)
Probably could clean it up a bit, but it's a lot easier to read than the other guy's ;)
If I'm reading your question right, you want a count of all pairs where the 2nd item is double the first. (and the 14 in the first list is a typo). In which case a simple function like this should do the job:
#a = [2,4,8,16,32]
a = [-5, -10, 0, 16, 32]
count = 0
for i, x in enumerate(a):
# Stop before the list overflows
if i < len(a) - 1:
# If the next element is double the current one, increment the counter
if a[i+1] == x * 2:
count = count + 1
else:
break
print(count)
isActiveData = isActive["Data"]
isActiveDataLen = len(isActiveData)
if isActiveDataLen > 0:
while isActiveDataLen > 0:
isActiveDataLen -= 1
print (isActiveDataLen)
Result
10
9
8
7
6
5
4
3
2
1
0
if isActiveDataLen > 0:
while isActiveDataLen > 0:
isActiveDataLen -= 1
return (isActiveDataLen)
Result
10
I have a program like this. But with print, I can extract the numbers I want from the while loop. When I use return, the while loop only works once and I cannot continue the program. How can I solve the problem?
When you use a return statement, the function stops and returns a value. If you want to extract a given number you can put it in an int for example and then return it at the end of your loop. Or if you want to return multiple values you can return a tuple with all the values you need to return (still at the end of your loop)
Write a function div_3_5(start, end) that computes the number of integers from start up to, but not including end that are divisible by 3 or 5 using a while loop.
NOTE: I must use a while loop inside a function for this exercise (i understand that a for loop is best).
Examples:
div_3_5(7, 27) evaluates to 9 ( numbers divisible by 3 or 5 in that range: 9,10,12,15,18,20,21,24,25)
I really don't understand why or what I'm doing and can someone to explain where i went wrong.
This is my code so far:
count = 0
def div_3_5(start, end):
while start < end:
if start%3 == 0 or start%5 == 0:
count + 1
start = start + 1
start + 1
return count
This obviously isn't complete or correct and the current error I'm getting is:
Expected Output:
div_3_5(7, 27) -> 9
Test Result: 0 != 9
There a few tips that would help here.
The mod operation % will return the remainder of an object so it a number is divisible by another the mod will be 0, for example 6 % 3 == 0 returns true.
A while loop isn't the best for this opertation, better would be a for loop
for i in range(start, end+1):
This wil fix the infinite loop.
This is how I would write it:
def div_3_5(start, end):
count = 0
for i in range(start, end + 1):
if i % 3 == 0 or i % 5 == 0:
count += 1
return count
start = 1
end = 10
count = div_3_5(start, end)
print(count)
Python has a modulus operator (%) which returns the remainder of A/B (10%4 == 2).
In your case, you would be looking for numbers which have a remainder of 0 when divided by 3 or 5
(i.e x%3 == 0 OR x%5 == 0).
Finally, the last elif where you ask elif start >= end is unnecessary because you stated that as the condition when you created the loop. Instead, try replacing those 2 lines with start = start + 1
The answer i found was:
def div_3_5(start, end):
count = 0
while start < end:
if start % 3 == int() or start % 5 == int():
count += 1
start = start + 1
return count
You need no loops to accomplish this task, here is simple -and fun- mathematical method that Python allows us to implement easily:
- One, create a set from 0 to the end with steps of 3s, i.e. {0,3,6,...end} this will get you all the elements that are divisible 3 within the boundary of your end (while keeping the end not included), in Python, this is done this way: set_of_3=set(range(0,b,3)) simple eh?
- Two, do the same but for the 5s, set_of_5=set(range(0,b,5))
- Three, add these sets together: set_of_all=set_of_3.union(set_of_5)
Now you got all the elements divisible by 3 and 5 from 0 to end, but you don't want that, you want from beginning to end, simply, just remove all numbers from 0 to your beginning from the set_of_all, by: result = set_of_all - set(range(0,a)) and just return the len() of that result. Your complete code:
def div_3_5(start,end):
set_of_3 = set(range(0,end,3))
set_of_5 = set(range(0,end,5))
set_of_all = set_of_3.union(set_of_5)
result = set_of_all - set(range(0,start))
return len(result)
A bit convoluted I know, but fun! At least for me. Hope this helps.
EDITED
Yeah I didn't notice you said you must use while loop, you can do this version of your code:
def div_3_5(start,end):
list = []
while start<end:
if start%3==0 or start%5==0:
list.append(start)
start+=1
return len(list)
Use the power of Python and forget these C-ish methods, and regarding what is wrong with your code, the line:
count + 1 doesn't work in Python, you have to do this: count+=1
def my_gen():
number = 1
fact = 1
fact = fact * number //Trying to calculate factorial
yield fact
number = number + 1
a = my_gen()
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
Trying to print the output for the first five natural numbers.
Expected output: 1 1 2 6 24
obtained output: 1 1 1 1 1
How can i do this??.Any help is appreciated
If you want to write this as a generator, you might want to look up how that works. The generator somehow has to to repeatedly yield a value, your function just provides a single yield, i.e. there is no "next". A fix, working for arbitrarily sized factorials, could involve itertools.count like so:
from itertools import count
def factorial():
res = 1
for x in count(1):
res = x*res
yield res
This starts with the value 1, after each iteration multiplying with the next higher number, and yielding that result.
Should you want to get the first value, 1, twice, then insert another yield res before entering the for-loop.
This may help you to solve your problem.
def my_gen(num):
if num < 0:
return 0
elif num == 0:
return 1
else:
for i in range(1,num + 1):
factorial = factorial*i
return factorial
a = 1
print(my_gen(a))
a = a+1
print(my_gen(a))
a = a+1
print(my_gen(a))
a = a+1
print(my_gen(a))
a = a+1
print(my_gen(a))
Here is the tested code
from itertools import count
def factorial():
res = 1
for x in count(1):
yield res
res = x*res
fs = factorial()
for item in range(10):
print(next(fs))
def factorial(x):
start = 0
fact = 1
while start <= x:
yield fact
start = start + 1
fact = fact * start
fact = factorial(5)
print(next(fact))
print(next(fact))
print(next(fact))
print(next(fact))
I've decided I want to work on the Euler problems in order to improve my Python skills, but I ran into a problem with the first one. You see, I wrote the program I thought would work trying to get an answer, and compared it to the one found on the solutions page located here. Here is the code that I wrote:
total = 0
for x in range(1000):
if x % 5 != 0 and x % 3 != 0:
total += x
print(total)
This gives me the answer 266,332, when the correct answer is 233,168 according to the solution linked before. I don't know why I got the wrong answer, and any help would be appreciated. Thanks!
You're missing a not in your application of De Morgan's Law:
total = 0
for x in range(1000):
if not (x % 5 != 0 and x % 3 != 0):
total += x
print(total)
not (x % 5 != 0 and x % 3 != 0) is equivalent to x % 5 == 0 or x % 3 == 0, the latter of which is stated in the page you link as the equivalent not x%5 or not x%3.
You are using the wrong condition. You have to test, when the rest is 0? With 3 and with 5. Additionally you have to use OR instead AND because you want both group of numbers.
If you use AND you are going to get only the numbers that are multiple of both, multiple of 3 and multiple of 5.
Try:
total = 0
for x in range(1000):
if x % 5 == 0 or x % 3 == 0:
total += x
print(total)
A couple of things are wrong with the program. For starters, your if statement checks the wrong condition--it checks to see whether or not it is NOT divisible by 3 or 5. It should be if x%3==0 or x%5==0:
Second, you have an indentation error, so nothing is being executed by the if statement. Indent the total+=x statement.
Your final code will look like this:
total = 0
for x in range(1000):
if x % 5 == 0 or x % 3 == 0:
total += x
print(total)
Best of luck, and happy coding!
try this:
def sumOfMultiples(number):
sum = 0
for i in range(1,number):
if i % 2 == 0 or i % 3 == 0:
sum += i
return sum
print (sumOfMultiples(15))