Velocity Reviews > Counting how many chars equal to a given char are in the beginning of a string

# Counting how many chars equal to a given char are in the beginning of a string

Stormbringer
Guest
Posts: n/a

 12-22-2003
Hi,

Given a string s and a char c, is there a short & elegant way to
determine how many consecutive occurences of c are in the beginning of
s ?

For example if s = ">>>>message1" and c = ">" then the number I am
looking for is 4 (the string begins with 4 '>').

Thanks,
Andrei

Jeff Epler
Guest
Posts: n/a

 12-22-2003
Here are several ways:

def count_initial(s, c):
return len(s) - len(s.lstrip(c))

def count_initial(s, c):
r = "^" + re.escape(c) + "*"
m = re.match(r, s)
return len(m.group(0))

# enumerate in 2.3
def count_initial(s, c):
for i, j in enumerate(s):
if j != c: break
return i

# itertools in 2.3
def count_initial(s, c):
return len(list(itertools.takewhile(lambda x: x==c, s)))

Jeff

Skip Montanaro
Guest
Posts: n/a

 12-22-2003

Andrei> Given a string s and a char c, is there a short & elegant way to
Andrei> determine how many consecutive occurences of c are in the
Andrei> beginning of s ?

Andrei> For example if s = ">>>>message1" and c = ">" then the number I
Andrei> am looking for is 4 (the string begins with 4 '>').

def howmanyatstart(s, pfx):
return (len(s) - len(s.lstrip(pfx)))/len(pfx)

? This works for prefixes which are longer than a single character:

>>> howmanyatstart(">>>>message1", '>')

4
>>> howmanyatstart("bobbobbob>>>>message1", 'bob')

3

Skip

vincent wehren
Guest
Posts: n/a

 12-22-2003
"Stormbringer" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed) om...
| Hi,
|
| Given a string s and a char c, is there a short & elegant way to
| determine how many consecutive occurences of c are in the beginning of
| s ?
|
| For example if s = ">>>>message1" and c = ">" then the number I am
| looking for is 4 (the string begins with 4 '>').

def getc(s, c):
"""
Get the number of consecutive occurrences of given char c
at the beginning of given string s.
"""
cnt = 0
while 1:
try:
if s[cnt] == c:
cnt += 1
else:
return cnt
except IndexError:
return cnt

c = '>'
print getc(">>>>Message", c) #prints 4
print getc(" >>>>Message", c) #prints 0
print getc (">>>", c) #prints 3

Maybe not the most elegant or shortest, but it works...

HTH,

Vincent Wehren

|
| Thanks,
| Andrei

vincent wehren
Guest
Posts: n/a

 12-22-2003
"vincent wehren" <(E-Mail Removed)> schrieb im Newsbeitrag
news:bs7nrc\$ubp\$(E-Mail Removed)1.nb.home.nl...
| "Stormbringer" <(E-Mail Removed)> schrieb im Newsbeitrag
| news:(E-Mail Removed) om...
| | Hi,
| |
| | Given a string s and a char c, is there a short & elegant way to
| | determine how many consecutive occurences of c are in the beginning of
| | s ?
| |
| | For example if s = ">>>>message1" and c = ">" then the number I am
| | looking for is 4 (the string begins with 4 '>').
|
|
| def getc(s, c):
| """
| Get the number of consecutive occurrences of given char c
| at the beginning of given string s.
| """
| cnt = 0
| while 1:
| try:
| if s[cnt] == c:
| cnt += 1
| else:
| return cnt
| except IndexError:
| return cnt
|
| c = '>'
| print getc(">>>>Message", c) #prints 4
| print getc(" >>>>Message", c) #prints 0
| print getc (">>>", c) #prints 3
|
| Maybe not the most elegant or shortest, but it works...

Looking at Jeff's proposed solutions, I would like to replace
the "Maybe" part in the above sentence with "Definitively"...

Isn't Python great?

Vincent

Vincent Wehren

|
| HTH,
|
| Vincent Wehren
|
|
| |
| | Thanks,
| | Andrei
|
|

Jeff Epler
Guest
Posts: n/a

 12-22-2003
On Mon, Dec 22, 2003 at 03:16:41PM -0600, Skip Montanaro wrote:
>
> def howmanyatstart(s, pfx):
> return (len(s) - len(s.lstrip(pfx)))/len(pfx)
>
> ? This works for prefixes which are longer than a single character:
>
> >>> howmanyatstart(">>>>message1", '>')

> 4
> >>> howmanyatstart("bobbobbob>>>>message1", 'bob')

> 3

strip() doesn't work that way:
>>> "bbbbbbbxxx".strip("bob")

'xxx'

Skip Montanaro
Guest
Posts: n/a

 12-22-2003
>>>>> "Jeff" == Jeff Epler <(E-Mail Removed)> writes:

Jeff> On Mon, Dec 22, 2003 at 03:16:41PM -0600, Skip Montanaro wrote:
>>
>> def howmanyatstart(s, pfx):
>> return (len(s) - len(s.lstrip(pfx)))/len(pfx)
>>
>> ? This works for prefixes which are longer than a single character:
>>
>> >>> howmanyatstart(">>>>message1", '>')

>> 4
>> >>> howmanyatstart("bobbobbob>>>>message1", 'bob')

>> 3

Jeff> strip() doesn't work that way:
>>>> "bbbbbbbxxx".strip("bob")

Jeff> 'xxx'

Then it looks like a bug in one or the other to me.

Skip

Jeff Epler
Guest
Posts: n/a

 12-22-2003
On Mon, Dec 22, 2003 at 04:06:44PM -0600, Skip Montanaro wrote:
> Then it looks like a bug in one or the other to me.

Add 'assert len(c) == 1' at the top of mine, then.

Jeff

Skip Montanaro
Guest
Posts: n/a

 12-22-2003
>>>>> "Jeff" == Jeff Epler <(E-Mail Removed)> writes:

Jeff> On Mon, Dec 22, 2003 at 03:16:41PM -0600, Skip Montanaro wrote:
>>
>> def howmanyatstart(s, pfx):
>> return (len(s) - len(s.lstrip(pfx)))/len(pfx)
>>
>> ?

Jeff> strip() doesn't work that way:
>>>> "bbbbbbbxxx".strip("bob")

Jeff> 'xxx'

Skip> Then it looks like a bug in one or the other to me.

I retract my statement. It's a bug in my code. help("".lstrip) shows why:

lstrip(...)
S.lstrip([chars]) -> string or unicode

Return a copy of the string S with leading whitespace removed.
If chars is given and not None, remove characters in chars instead.
If chars is unicode, S will be converted to unicode before stripping

Note the second sentence.

Sorry for the flub.

Skip

Oren Tirosh
Guest
Posts: n/a

 12-23-2003
On Mon, Dec 22, 2003 at 12:04:21PM -0800, Stormbringer wrote:
> Hi,
>
> Given a string s and a char c, is there a short & elegant way to
> determine how many consecutive occurences of c are in the beginning of
> s ?
>
> For example if s = ">>>>message1" and c = ">" then the number I am
> looking for is 4 (the string begins with 4 '>').

re.match('>*', s).end()

Oren