Reputation: 1041
I want to know the number of zeros which first appear in a list, before any other number.
For example:
L1 = [0, 0, 0, 0, 0, 1, 2]
- the output should be 5, which is the number of zeros.
L2 = [1, 0, 0, 0, 0, 0, 2]
- the output should be zero. Although there are 5 zeros in this list but the list starts with 1.
Here is my code:
k = 0
for i in L1:
while i == 0:
k = k + 1
It doesn't work though. I think it is an infinite loop, but I don't know why.
Upvotes: 1
Views: 192
Reputation: 4010
What you're thinking while does, is carry on as normal until the condition isn't met. What it really does, is repeat the code inside of the while as a loop until the condition isn't met.
Here's my solution, which tries to work as similarly to yours as possible, by carrying on counting until the number isn't a 0 then looking at how far it's come and breaking out of the for loop.
k = 0
for index,item in enumerate(L1):
if item != 0:
k = len(L1[:index])
break
Upvotes: 0
Reputation: 881453
Think of what will happen the first time i
gets set to 0
.
The while
loop will start and never stop, because i
is not changed within that loop.
You would be better off with something as per the following transcript, a slight modification of yours:
>>> list1 = [0,0,0,0,0,1,2]
>>> count = 0
>>> for item in list1:
... if item == 0:
... count = count + 1
... else:
... break
...
>>> print count
5
or the slightly shorter variation which breaks immediately for a non-zero value, adding one otherwise.:
>>> list1 = [0,0,0,0,0,1,2]
>>> count = 0
>>> for item in list1:
... if item != 0: break
... count = count + 1
...
>>> print count
5
Upvotes: 5
Reputation: 1302
My answer expands on paxdiablo's. Thanks to him for clarifying OP's intent with the L2 case, which I had misread.
While itertools
is handy for this kind of thing, at the point you're at, I'd say mastering the basic language features is worthwhile.
In your code, you do this:
L1 = [0, 0, 0, 0, 0, 1, 2]
k = 0
for i in L1:
while i == 0:
k = k + 1
When you run that chunk of code on L1
, it loops forever. Here's why:
for
causes the code that's enclosed (meaning the code below that's set aside by indentation) to loop. So, your for i in L1:
loop runs everything indented below it once for each thing in L1.
But, while
does something similar. while
tells Python to run the indented code below it over and over until the condition on the while
statement is False
.
So, in the case of L1
, the first time through the for
loop, i
gets set to 0. Then, while i == 0:
says to execute the code enclosed, k = k + 1
, over and over again until i
is no longer zero. Unfortunately, since the code in the while
loop does not change the value of i
, i
will be zero until the end of time, so it runs forever, repeatedly adding one to k
.
What you're looking for is an if
statement, which will not loop. It will just run the enclosed code, or not, based on whether its test is true. So, instead of:
while i == 0:
k = k + 1
you can use
if i == 0:
k = k + 1
else:
break
Then, each time through the for
loop, the code asks whether i
is zero, and if so, only once, it adds one to k
, then goes on to the next list element. To cover your L2 case, if you hit a number that is not zero, break
exits the for
loop and stops counting.
The answer presented with itertools
is clever, useful, good to know, and probably what you'd want to use for very large lists, but since it appears you're just learning the language (and probably learning your first language), it's worth learning how to use for
, while
, and if
correctly.
Upvotes: 0
Reputation: 304
As other commentators have said, the problem in your code is that you seem to misunderstand the meaning of the while
keyword. That aside, for problems like these, I often prefer a more functional style:
>>> import itertools
>>> k = len(list(itertools.takewhile(lambda x: x == 0, L1)))
>>> k
5
>>> k = len(list(itertools.takewhile(lambda x: x == 0, L2)))
>>> k
0
If you are just beginning to get to know Python, playing around with what the itertools
offers is well worth it.
Upvotes: 2