It depends on what you mean by efficiency.
If you intend to minimize the runtime, you will basically have to iterate over the character of the string character by character, analyzing the runs of consecutive zeros and tracking the longest, something like:
def longRunZeros(s): big = 0 curr = 0 for c in s: if c == '0': curr += 1 else: if curr > big: big = curr curr = 0 if curr > big: big = curr return big print longRunZeros('0010011010000')
If you are talking about program effectiveness, just do:
def longRunZeros(s): return max(len(i) for i in s.split('1'))
instead.
It will not necessarily work faster, but it will free you so that you have more time, perhaps to analyze whether you even need the download speed for this operation. It will also almost certainly be less error prone to its length.
As for speed, think about it. With line 25M, the character-by-character method takes 2.826 seconds of processor time for a million iterations. The split method takes 3.186 seconds for the same workload 1 .
So, if your line is much longer than 25M, or you need to do it much more than a million times, it will not make much difference, and I would prefer to choose a method that is easier for me as a developer.
Addendum: after I said that differential differential performance is not relevant here, I am a bit hypocritical to mention that the other method shown by John La Roy in the comment seems to be a little faster than mine.
But, for completeness, I will suffer from slings and arrows to indicate this:
def longRunZeros(s): return len(max(s.split('1')))
It appears that the average is around 1.092 , which doubles the speed of the above character symbol.
1 These numbers are the average of five runs in my environment, and I cannot guarantee that they will be held anywhere else.
If you have ever participated in optimization efforts, you should know that it should be measured in your real environment, and not depending on which one is a random (but very beautiful) person on the Internet :-)