[Tutor] Consecutive_zeros

avi.e.gross at gmail.com avi.e.gross at gmail.com
Mon Jul 4 12:49:20 EDT 2022


Thanks for reminding me Peter. This may be a bit off topic for the original
question if it involved learning how to apply simple algorithms in Python
but is a good exercise as well for finding ways to use various built-in
tools perhaps in a more abstract way.

What Peter did was a nice use of the built-in split() function which does
indeed allow the removal of an arbitrary number of ones but, as he notes,
his solution, as written, depends on there not being anything except zeroes
and ones in the string. 

So I went back to my previous somewhat joking suggestion and thought of a
way of shortening it as the "re" module also has a regular-expression
version called re.split() that has the nice side effect of including an
empty string when I ask it to split on all runs of non-zero. 

re.split("[^0]", "1010010001000010000001")
['', '0', '00', '000', '0000', '000000', '']

That '' at the end of the resulting list takes care of the edge condition
for a string with no zeroes at all:

re.split("[^0]", "No zeroes")
['', '', '', '', '', '', '', '', '', '']

Yes, lots of empty string but when you hand something like that to get
lengths, you get at least one zero which handles always getting a number,
unlike my earlier offering which needed to check if it matched anything.

So here is a tad shorter and perhaps more direct version of the requested
function which is in effect a one-liner:

def consecutive_zeros(string):
    return(max([len(zs) for zs in re.split("[^0]", string)]))

The full code with testing would be:

import re

def consecutive_zeros(string):
    return(max([len(zs) for zs in re.split("[^0]", string)]))

def testink(string, expected):
    print(str(consecutive_zeros(string)) + ": " + string + "\n" +
str(expected) + ": expected\n")

print("testing the function and showing what was expected:\n")
testink("1010010001000010000001", 6)
testink("00000000000000000000000000", 26)
testink("1111", 0)
testink("begin1x00x110001END", 3)
testink("Boy did you pick the wrong string!", 0)

The output is:

testing the function and showing what was expected:

6: 1010010001000010000001
6: expected

26: 00000000000000000000000000
26: expected

0: 1111
0: expected

3: begin1x00x110001END
3: expected

0: Boy did you pick the wrong string!
0: expected


-----Original Message-----
From: Tutor <tutor-bounces+avi.e.gross=gmail.com at python.org> On Behalf Of
Peter Otten
Sent: Monday, July 4, 2022 3:51 AM
To: tutor at python.org
Subject: Re: [Tutor] Consecutive_zeros

On 03/07/2022 23:05, Anirudh Tamsekar wrote:
> Hello All,
>
> Any help on this function below is highly appreciated.
> Goal: analyze a binary string consisting of only zeros and ones. Your 
> code should find the biggest number of consecutive zeros in the string.
>
> For example, given the string:
> Its failing on below test case

In case you haven't already fixed your function here's a hint that is a bit
more practical than what already has been said.

>
> print(consecutive_zeros("0"))
> It should return 1. Returns 0
>
> I get the max(length) as 1, if I print it separately
>
>
> def consecutive_zeros(string):
>      zeros = []
>      length = []
>      result = 0
>      for i in string:
>          if i == "0":
>              zeros.append(i)

         else:
>              length.append(len(zeros))
>              zeros.clear()
>              result = max(length)

At this point in the execution of your function what does zeros look like
for the succeeding cases, and what does it look like for the failing ones?
Add a print(...) call if you aren't sure and run
consecutive_zeros() for examples with trailing ones, trailing runs of zeros
that have or don't have the maximum length for that string.

How can you bring result up-to-date?

>      return result

PS: Because homework problems are often simpler than what comes up in the
"real world" some programmers tend to come up with solutions that are less
robust or general. In that spirit I can't help but suggest

 >>> max(map(len, "011110000110001000001111100".split("1")))
5

which may also be written as

 >>> max(len(s) for s in "011110000110001000001111100".split("1"))
5

Can you figure out how this works?
What will happen if there is a character other than "1" or "0"in the string?
_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



More information about the Tutor mailing list