>>> k = 8
>>> for i in range(k):
print i
k -= 3
print k
Above the is the code which prints numbers from 0-7 if I use just print i in the for loop.
I want to understand the above code how it is working, and is there any way we can update the value of variable used in range(variable) so it iterates differently.
Also why it always iterates up to the initial k value, why the value doesn't updated.
I know it's a silly question, but all ideas and comments are welcome.
You can't change the range after it's been generated. In Python 2, range(k) will make a list of integers from 0 to k, like this: [0, 1, 2, 3, 4, 5, 6, 7]. Changing k after the list has been made will do nothing.
If you want to change the number to iterate to, you could use a while loop, like this:
k = 8
i = 0
while i < k:
print i
k -= 3
i += 1
The expression range(k) is evaluated just once, not on every iteration. You can't set k and expect the range(k) result to change, no. From the for statement documentation:
The expression list is evaluated once; it should yield an iterable object.
You can use a while loop instead:
i = 0
k = 8
while i < k:
print i
i += 1
k -= 3
A while loop does re-evaluate the test each iteration. Referencing the while statement documentation:
This repeatedly tests the expression and, if it is true, executes the first suite
If you do want to change k and affect the loop you need to make sure you are iterating over mutable object. For example:
k = list(range(8))
for i in k:
print(i)
k.pop()
k.pop()
k.pop()
print(k)
Or alternatively:
k = list(range(8))
for i in k:
print(i)
k[:] = k[:-3]
print(k)
Both will result with
0
[0, 1, 2, 3, 4]
1
[0, 1]
you could do it like this ,I think, but I dont know if this is what you want.
def to_infinity():
index = 0
while True:
yield index
index += 1
for i in to_infinity():
print(i)
Related
I need to change the condition so that the loop is finite and list_ contains following values:
1 2 4 8 16 32 64
This is what I have in python, and I am struggling to understand what exactly needs to be changed and why.
list_ = []
i = 0
while i >= 0: # change the condition
list_.append(2 ** i)
i += 1
print(list_)
I suggest to use a for-loop instead of a while loop.
list_ = []
for i in range(7):
list_.append(2 ** i)
print(list_)
If you want to be very pythonic, then you can use a list comprehension:
list_ = [2 ** i for i in range(7)]
With a while a breaking condition is required (this implementation is to highlight the break)
out = []
i = 0
while True:
if i > 6:
break
out.append(2**i)
i += 1
print(out)
or with a list comprehension
print([2**i for i in range(6+1)])
Looks like you'll only need to switch the while condition in the loop. Rather than have a lower bound, you'll need to update with an upper bound - basically a "loop until" condition.
list_ = []
i = 0
while i <= 6: # change the condition
list_.append(2 ** i)
i += 1
print(list_). # [1, 2, 4, 8, 16, 32, 64]
But you can simplify this even further, with the help of a list comprehension. This is just a fancy (and bit more efficient) way of writing a for loop in python. Its more efficient because it doesn't need to call list.append within each loop iteration.
>>> [2 ** i for i in range(7)]
[1, 2, 4, 8, 16, 32, 64]
You could use while i <= 6: so that you while loop counts up to i=6.
However, I would recommend to use a for-loop with range(6) as a condition. So that your loop looks like the following:
for i in range(7):
…
This is just an alternative way, where i also counts up to the value of 6. using a for-loop would be good practice, as it saves you to declare i previously.
I don't get how a "for" loop that iterates through the elements of a list can be out of range.
First part seems to be okay as I can print it.
import random
def random_list(n):
l = []
for i in range(0,n):
l.append(random.randint(0,n))
return l
def maximum(n):
x = 0
b = random_list(n)
for i in b:
if b[i] > x:
x = b[i]
print (maximum(10))
This:
for i in b:
if b[i] > x:
x = b[i]
Iterates over the elements of b, not the indices. Change it to
for i in b:
if i > x:
x = i
You also need to return something from your function, probably x.
Considering that you know how to iterate over a list in python, the error could be due to randint, which generates an integer in the interval [low, high]. This means high is a possible output, while the highest index in your program is high - 1.
For example,
random.randint(0, 0)
gives 0.
Similarly, random.randint(10) can return 10.
If you don't understand how to iterate over a list in Python, consider a simple example:
Take the list below:
myList = [1, 3, 5, 7, 9]
Now, there are two ways to iterate over the list:
Directly accessing elements:
for element in myList:
print(element, end=" ")
This gives the output:
1 3 5 7 9
Accessing elements using indices
for idx in range(len(myList)):
print(idx, ":", myList[idx], end=" ")
This gives the output:
0:1 1:3 2:5 3:7 4:9
For example, I have two lists:
A=['a','b','c']
B=['a','a','b','c']
I want my output to look like:
[2,1,1]
Here is what I tried:
P=np.ndarray(shape=3, dtype=int)
count=0
d=0
for i in A:
for j in B:
if i==j:
count+=1
P[d]=count
d+=1
But I am getting
[2,3,4]
as output. What is going wrong?
Just use count method:
A=['a','b','c']
B=['a','a','b','c']
[B.count(x) for x in A]
The methods as suggested by #CarlesMitjans or #WillenVanOnsem are better solutions than this, but the reason your method does not work is that you need to initialise your count variable inside the first loop (and also indent the d+=1 line):
P = np.ndarray(shape=3, dtype=int)
count = 0
d = 0
for i in A:
count = 0
for j in B:
if i == j:
count += 1
P[d] = count
d += 1
which gives:
>>> P
array([2, 1, 1])
If the elements are hashable, you can simply use a counter you then transform back into a list. Like:
from collections import Counter
ctr = Counter(B)
result = [ctr[x] for x in A]
This generates:
>>> [ctr[x] for x in A]
[2, 1, 1]
This works in O(|A|+|B|) with |A| the numbers in A and |B| the numbers in B (given dictionary lookup works in O(1), which is nearly always the case).
If the elements can not be hashed (for instance lists, dictionaries, objects,...), then you can use #CharlesMitjans answer, which runs in O(|A|×|B|) (which tends to be less efficient, but then you cannot take advantage of hashing).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I am trying to add a 0 after each even number, every time i run the code it infinitely prints the value of i, which is 0 every time.
I've tried this so far:
def linear_list (n):
x = []
for y in range (1, n+1):
x.append (y)
return x
n = int (input ("Enter the lenght of the list: "))
alist = linear_list (n)
for i in alist:
print (i)
if i % 2 == 0:
alist.append(0)
print (alist)
But for i >= 2my code is printing infinite zeroes:
Enter the lenght of the list: 5
0
0
0
0
...
Expected output:
[1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0, 9, 10, 0]
How can achieve the correct list?
Make it work, make it right, make it fast
Here the make it work part.
You are modifying the list and iterating it at the same time.
Try:
otherlist = []
for i in alist:
print (i)
otherlist.append(i)
if i % 2 == 0:
otherlist.append(0)
print (otherlist)
You're increasing the alist length every time you append to it, and since you're looping through it you will never exit the loop - the list never ends. You don't want to change the list, but the value within it, so enumerate it:
for i, v in enumerate(alist):
print (v)
if v % 2 == 0:
alist[i] = v * 10 # assuming it's a number, use v + "0" if its a string
The iterator create by the for loop is a separate object from the list you iterate over. Your for loop is similar to a while loop like
itr = iter(a)
while True:
try:
i = next(itr)
except StopIteration:
break
if i % 2 == 0:
a.append(0)
a.append always adds a 0 to the end of the list, without affecting the current position of the iterator. Since 0 is even, once the iterator reaches the what was the end of the list when you started the loop, it sees a 0, and so another 0 gets added to the end of the list. It continues reading the next 0 and adding another 0, on and on, forever.
Technically, you can do what you want, but it's rather tricky and very easy to get wrong. (It took me about 8 tries to get this example right.) The trick is to create a separate iterator explicitly, one that you can access in the body of the loop, rather than letting the for loop generate the iterator for you. This allows you to insert a 0 after the current value in the list, then skip over the new 0 so that you won't see it on the next iteration of the loop.
Don't actually do this if you can avoid it: it is far simpler to create a new list that replaces the old list after the loop.
That said, on with the show:
a = range(10)
itr = enumerate(a) # A list of index, value pairs
for index, value in itr:
if value % 2 == 0:
i = index + 1
a[i:i] = [0] # Put a 0 after the current position
next(itr) # Skip over the 0 you just added
assert a == [0, 0, 1, 2, 0, 3, 4, 0, 5, 6, 0, 7, 8, 0, 9]
You can shorten this a bit by starting the index at 1 instead of 0, effectively pre-adding 1 to each index before you need it.
a = range(10)
itr = enumerate(a, start=1)
for i, value in itr:
if value % 2 == 0:
a[i:i] = [0]
next(itr)
How to increment the outer iterator from the inner loop?
To be more precise:
for i in range(0,6):
print i
for j in range(0,5):
i = i+2
I am getting
0
1
2
3
4
5
, but I want 0,2,4
Above is the simpilfied idea what I want to acheive.
Here is my Java code:
str1="ababa"
str2="aba"
for(int i =0; i < str1.length; i++)
for(int j =0; j < str2.length; j++)
if str1[i+j]!=str[j]
break;
if( j ==str2.length -1)
i=i+str2.length;
It seems that you want to use step parameter of range function. From documentation:
range(start, stop[, step]) This is a versatile function to create
lists containing arithmetic progressions. It is most often used in for
loops. The arguments must be plain integers. If the step argument is
omitted, it defaults to 1. If the start argument is omitted, it
defaults to 0. The full form returns a list of plain integers [start,
start + step, start + 2 * step, ...]. If step is positive, the last
element is the largest start + i * step less than stop; if step is
negative, the last element is the smallest start + i * step greater
than stop. step must not be zero (or else ValueError is raised).
Example:
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 11) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> range(0, 30, 5) [0, 5, 10, 15, 20, 25]
>>> range(0, 10, 3) [0, 3, 6, 9]
>>> range(0, -10, -1) [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
>>> range(0) []
>>> range(1, 0) []
In your case to get [0,2,4] you can use:
range(0,6,2)
OR in your case when is a var:
idx = None
for i in range(len(str1)):
if idx and i < idx:
continue
for j in range(len(str2)):
if str1[i+j] != str2[j]:
break
else:
idx = i+j
You might just be better of using while loops rather than for loops for this. I translated your code directly from the java code.
str1 = "ababa"
str2 = "aba"
i = 0
while i < len(str1):
j = 0
while j < len(str2):
if not str1[i+j] == str1[j]:
break
if j == (len(str2) -1):
i += len(str2)
j+=1
i+=1
In python, for loops iterate over iterables, instead of incrementing a counter, so you have a couple choices. Using a skip flag like Artsiom recommended is one way to do it. Another option is to make a generator from your range and manually advance it by discarding an element using next().
iGen = (i for i in range(0, 6))
for i in iGen:
print i
if not i % 2:
iGen.next()
But this isn't quite complete because next() might throw a StopIteration if it reaches the end of the range, so you have to add some logic to detect that and break out of the outer loop if that happens.
In the end, I'd probably go with aw4ully's solution with the while loops.
I read all the above answers and those are actually good.
look at this code:
for i in range(1, 4):
print("Before change:", i)
i = 20 # changing i variable
print("After change:", i) # this line will always print 20
When we execute above code the output is like below,
Before Change: 1
After change: 20
Before Change: 2
After change: 20
Before Change: 3
After change: 20
in python for loop is not trying to increase i value. for loop is just assign values to i which we gave. Using range(4) what we are doing is we give the values to for loop which need assign to the i.
You can use while loop instead of for loop to do same thing what you want,
i = 0
while i < 6:
print(i)
j = 0
while j < 5:
i += 2 # to increase `i` by 2
This will give,
0
2
4
Thank you !
for a in range(1):
for b in range(3):
a = b*2
print(a)
As per your question, you want to iterate the outer loop with help of the inner loop.
In outer loop, we are iterating the inner loop 1 time.
In the inner loop, we are iterating the 3 digits which are in the multiple of 2, starting from 0.
Output:
0
2
4