Mailing List Archive

count consecutive elements
I want to to display a number or an alphabet which appears mostly
consecutive in a given string or numbers or both
Examples
s= ' aabskaaabadcccc'
output: c
# c appears 4 consecutive times
8bbakebaoa
output: b
#b appears 2 consecutive times

I thought about set the string then and for each element loop the string
to check if equal with element set element if so count =+1 and check if
next to it is not equal add counter value to list with same index as in
set.
However I'm fighting to code it and the counting numbers are not right:


s = 'aabskaaabadcccc'

c = 0
t = set(s) # set of characters in s
li=[0,0,0,0,0,0] # list for counted repeats

for x in t:
h = t.index(x)
for i in s:
if i == x:
m = s.index(i)
c +=1
if s[m+1] != x: # if next element is not x
if c > li[h]:
li[h]= c
c = 0

for i in t:
n = t.index(i)
print(i,li[n])

--
Thanks
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-13, Bischoop <Bischoop@vimart.net> wrote:
> t = set(s) # set of characters in s

I have this one changed to:
t= list(set(s))
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-13 21:20, Bischoop wrote:
> I want to to display a number or an alphabet which appears mostly
> consecutive in a given string or numbers or both
> Examples
> s= ' aabskaaabadcccc'
> output: c
> # c appears 4 consecutive times
> 8bbakebaoa
> output: b
> #b appears 2 consecutive times

I'd break the problem into two parts:

1) iterate over your thing (in this case, a string) and emit the item
and its correpsonding count of consecutive matches.

2) feed that into something that finds the longest run(s) output by
that.

So off the cuff, something like

def consecutive_counter(seq):
# I'm not sure if there's something
# like this already in itertools
cur = nada = object()
count = 0
for x in seq:
if x == cur:
count += 1
else:
if cur is not nada:
yield cur, count
cur = x
count = 1
if cur is not nada:
yield cur, count

def longest(seq):
results = []
biggest = 0
for item, count in seq:
if count > biggest:
results = [item]
biggest = count
elif count == biggest:
results.append(item)
return results, biggest

for s in (
"",
"a",
"aaa",
"aaabbb",
"aabskaaabadcccc",
"aabskaaakkkkkbadcccc",
):
print("Testing %r" % s)
print(repr(longest(consecutive_counter(s))))

-tkc




--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-13, Bischoop <Bischoop@vimart.net> wrote:

I know what was wrong:

> m = s.index(i)

I forgot that m will return first index of i.

So tried that way but still getting out of index although I that that
I'm making sure not to get out of index.

s = 'aabskaaabadcccch'

c = 0
t = list(set(s)) # list of characters in s
li=[0,0,0,0,0,0] # list for counted repeats
print(t)
for x in t:
h = t.index(x)
for index, i in enumerate(s):
maximus = len(s)
if i == x:
c += 1
if index < maximus:
if s[index +1] != x: # if next element is not x
if c > li[h]: #update c if bigger than existing
li[h] = c
c = 0
else:
if c > li[h]:
li[h] = c


for i in t:
n = t.index(i)
print(i,li[n])

print(f'{s[li.index(max(li))]} appears {max(li)} consecutive times')


--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On Wed, Jan 13, 2021 at 5:59 PM Tim Chase <python.list@tim.thechases.com>
wrote:

> On 2021-01-13 21:20, Bischoop wrote:
> > I want to to display a number or an alphabet which appears mostly
> > consecutive in a given string or numbers or both
> > Examples
> > s= ' aabskaaabadcccc'
> > output: c
> > # c appears 4 consecutive times
> > 8bbakebaoa
> > output: b
> > #b appears 2 consecutive times
>

I'm kind of partial to:

import collections
import typing


def get_longest(string: str) -> typing.Tuple[int, str]:
"""Get the longest run of a single consecutive character."""
dict_: typing.DefaultDict[str, int] = collections.defaultdict(int)
for left_ch, right_ch in zip(string, string[1:]):
if left_ch == right_ch:
dict_[left_ch] += 1

maximum = max((value, key) for key, value in dict_.items())

return maximum

HTH
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-13 18:20, Dan Stromberg wrote:
> I'm kind of partial to:
>
> import collections
> import typing
>
>
> def get_longest(string: str) -> typing.Tuple[int, str]:
> """Get the longest run of a single consecutive character."""
> dict_: typing.DefaultDict[str, int] =
> collections.defaultdict(int) for left_ch, right_ch in zip(string,
> string[1:]): if left_ch == right_ch:
> dict_[left_ch] += 1
>
> maximum = max((value, key) for key, value in dict_.items())
>
> return maximum

seems to only return one value so seems to get odd results if I
specify something like

get_longest("aaabcccbbb")

which at least here tells me that "c" is the longest run, even though
aaa, bbb, and ccc are all runs of length 3. The OP didn't specify
what should happen in that case, so it would need some clarification.

-tkc



--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On Wed, Jan 13, 2021 at 6:20 PM Dan Stromberg <drsalists@gmail.com> wrote:

> On Wed, Jan 13, 2021 at 5:59 PM Tim Chase <python.list@tim.thechases.com>
> wrote:
>
>> On 2021-01-13 21:20, Bischoop wrote:
>> > I want to to display a number or an alphabet which appears mostly
>> > consecutive in a given string or numbers or both
>> > Examples
>> > s= ' aabskaaabadcccc'
>> > output: c
>> > # c appears 4 consecutive times
>> > 8bbakebaoa
>> > output: b
>> > #b appears 2 consecutive times
>>
>
> I'm kind of partial to:
>
> import collections
> import typing
>
>
> def get_longest(string: str) -> typing.Tuple[int, str]:
>
I just realized this has a kinda big bug. Don't use!
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
Am 13.01.2021 um 22:20 schrieb Bischoop:
> I want to to display a number or an alphabet which appears mostly
> consecutive in a given string or numbers or both
> Examples
> s= ' aabskaaabadcccc'
> output: c
> # c appears 4 consecutive times
> 8bbakebaoa
> output: b
> #b appears 2 consecutive times
>
>
You can let itertools.groupy find the groups.

max((len(tuple(group)), key) for key, group in itertools.groupby(s))
# (4, 'c')
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-14, Tim Chase <python.list@tim.thechases.com> wrote:
>
> seems to only return one value so seems to get odd results if I
> specify something like
>
> get_longest("aaabcccbbb")
>
> which at least here tells me that "c" is the longest run, even though
> aaa, bbb, and ccc are all runs of length 3. The OP didn't specify
> what should happen in that case, so it would need some clarification.
>
>

In that case maybe good solution would be to return three of them?

--
Thanks

--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-16 03:32, Bischoop wrote:
>> The OP didn't specify what should happen in that case, so it would
>> need some clarification.
>
> In that case maybe good solution would be to return three of them?

That's the solution I chose in my initial reply, you get a tuple back
of ([list of longest matches], length_of_longest_match)

-tkc


--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On Thu, Jan 14, 2021 at 2:01 PM Wolfram Hinderer via Python-list <
python-list@python.org> wrote:

> Am 13.01.2021 um 22:20 schrieb Bischoop:
> > I want to to display a number or an alphabet which appears mostly
> > consecutive in a given string or numbers or both
> > Examples
> > s= ' aabskaaabadcccc'
> > output: c
> > # c appears 4 consecutive times
> > 8bbakebaoa
> > output: b
> > #b appears 2 consecutive times
> >
> >
> You can let itertools.groupy find the groups.
>
> max((len(tuple(group)), key) for key, group in itertools.groupby(s))
> # (4, 'c')
>

Does anyone else find the documentation on itertools.groupby kind of
lacking?

I think it makes sense now that I've played around with it though.

Here's a revised solution:
def get_longest(string: str) -> typing.Tuple[int, typing.List[str]]:
"""Get the longest run of a single consecutive character."""
if not string:
return (0, [])
grouped = itertools.groupby(string)
grouped_with_lengths = [(len(list(value)), key) for key, value in
grouped]
max_count_and_letter = max(grouped_with_lengths)
max_count = max_count_and_letter[0]
result = (max_count, sorted(list_ for count, list_ in
grouped_with_lengths if count == max_count))
return result
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 17/01/2021 02:15, Dan Stromberg wrote:

IMO a good set of tests is much more important than type annotations ;)

> def get_longest(string: str) -> typing.Tuple[int, typing.List[str]]:
> """Get the longest run of a single consecutive character."""

May I ask why you artificially limit the signature to str?
If there were a signature, shouldn't it be something like

Iterable[E] --> Tuple[int, List[E]]

where E may be anything that has an equality operation?
As someone who has not yet looked seriously into typing: is there a way
to spell this?

> if not string:
> return (0, [])
> grouped = itertools.groupby(string)
> grouped_with_lengths = [(len(list(value)), key) for key, value in
> grouped]
> max_count_and_letter = max(grouped_with_lengths)
> max_count = max_count_and_letter[0]
> result = (max_count, sorted(list_ for count, list_ in
> grouped_with_lengths if count == max_count))
> return result

If you want to dabble some more here's a test case you might strive for
your function to pass:

"""
>>> class A:
... def __init__(self, x):
... self.x = x
... def __eq__(self, other):
... return self.x == other.x
... def __repr__(self):
... return self.x

>>> get_longest(map(A, "aaabbcccdaa"))
(3, [a, c])

"""
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 17/01/2021 02:15, Dan Stromberg wrote:

IMO a good set of tests is much more important than type annotations ;)

> def get_longest(string: str) -> typing.Tuple[int, typing.List[str]]:
> """Get the longest run of a single consecutive character."""

May I ask why you artificially limit the signature to str?
If there were a signature, shouldn't it be something like

Iterable[E] --> Tuple[int, List[E]]

where E may be anything that has an equality operation?
As someone who has not yet looked seriously into typing: is there a way
to spell this?

> if not string:
> return (0, [])
> grouped = itertools.groupby(string)
> grouped_with_lengths = [(len(list(value)), key) for key, value in
> grouped]
> max_count_and_letter = max(grouped_with_lengths)
> max_count = max_count_and_letter[0]
> result = (max_count, sorted(list_ for count, list_ in
> grouped_with_lengths if count == max_count))
> return result

If you want to dabble some more here's a test case you might strive for
your function to pass:

"""
>>> class A:
... def __init__(self, x):
... self.x = x
... def __eq__(self, other):
... return self.x == other.x
... def __repr__(self):
... return self.x

>>> get_longest(map(A, "aaabbcccdaa"))
(3, [a, c])

"""

--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-14, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
>
> If you want to know why, maybe you should insert print
> statements to see the values of critical variables and
> expression, especially in loops.
>
> Then compare the printed values with your expectations.
>
> Also, decompose into meaningful functions and test each
> function separately.
>
>

I sat to it again and solved it.

import timeit

run1 = '''

s = 'aabskaaaabadcccc'


lil = tuple(set(s)) # list of characters in s

li=[0,0,0,0,0,0] # list for counted repeats


for i in lil:
c = 0
h= lil.index(i)
for letter in s:
if letter == i:
c += 1
if c > li[lil.index(letter)]:
li[lil.index(letter)] = c
else:
c=0
continue

m = max(li)

for index, j in enumerate(li):
if li[index] == m:
print(f'{lil[index]} appears {m} consecutive times')


'''
print(timeit.timeit(stmt=run1, number=1))



output:
c appears 4 consecutive times
a appears 4 consecutive times
0.00013008200039621443


--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 19/01/2021 04:45, Bischoop wrote:

> I sat to it again and solved it.

Congratulations!

> lil = tuple(set(s)) # list of characters in s
>
> li=[0,0,0,0,0,0] # list for counted repeats

I see a minor problem here. What happens if s contains more than len(li)
characters?

> import timeit

Since you seem interested in performance: imagine that the input is a
very long string. Let's call the length N.

How often do you iterate over its characters?
How often does Tim's solution?
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 19/01/2021 04:45, Bischoop wrote:

> I sat to it again and solved it.

Congratulations!

> lil = tuple(set(s)) # list of characters in s
>
> li=[0,0,0,0,0,0] # list for counted repeats

I see a minor problem here. What happens if s contains more than len(li)
characters?

> import timeit

Since you seem interested in performance: imagine that the input is a
very long string. Let's call the length N.

How often do you iterate over its characters?
How often does Tim's solution?

--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 2021-01-19, Peter Otten <__peter__@web.de> wrote:
> On 19/01/2021 04:45, Bischoop wrote:
>
>> I sat to it again and solved it.
>
> Congratulations!
>
> > lil = tuple(set(s)) # list of characters in s
> >
> > li=[0,0,0,0,0,0] # list for counted repeats
>
> I see a minor problem here. What happens if s contains more than len(li)
> characters?
>

Thanks, I've created it when came to idea how to solve the problem and
then forgot that part, will have to update it with two additional line
of code.

>> import timeit
>
> Since you seem interested in performance: imagine that the input is a
> very long string. Let's call the length N.
>
> How often do you iterate over its characters?
>

Does it take time :-) I actually left it because seen guy in thread
were comparing their time results, I'm pretty much aware that mine
solution is time consuming and there are better ways to do it but
I wanted to finish what I started without any additional libraries
like itertools etc in the way that my knowledge allows. The idea with
for this tuple just came up in a first seconds when I look at that
and was not bothering about time or performance especially that later
on as you seen I had different problem to solve and which took me quite
a time and when I look at it today I think how couldn't I came with it
earlier and let myself stuck on it.

I'm happy that despite I've asked here I've finish it practically wthout
additional help and yeah ( Thanks to Stefan who just pointed me to look
at it from different prespective instead pointing what was wrong),
I'll iterate here n = x [x for x in lil], with big string it can make
difference. Now, when you asked me that question I came indeed for better
idea to do this. One loop during which I can append character if not in lil.

> How often does Tim's solution?

oh here Im stuck and dont understand what you mean?

--
Thanks
--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 19/01/2021 10:42, Bischoop wrote:
> On 2021-01-19, Peter Otten <__peter__@web.de> wrote:
>> On 19/01/2021 04:45, Bischoop wrote:
>>
>>> I sat to it again and solved it.
>>
>> Congratulations!
>>
>>> lil = tuple(set(s)) # list of characters in s
>>>
>>> li=[0,0,0,0,0,0] # list for counted repeats
>>
>> I see a minor problem here. What happens if s contains more than len(li)
>> characters?
>>
>
> Thanks, I've created it when came to idea how to solve the problem and
> then forgot that part, will have to update it with two additional line
> of code.
>
>>> import timeit
>>
>> Since you seem interested in performance: imagine that the input is a
>> very long string. Let's call the length N.
>>
>> How often do you iterate over its characters?
>>
>
> Does it take time :-) I actually left it because seen guy in thread
> were comparing their time results, I'm pretty much aware that mine
> solution is time consuming and there are better ways to do it but
> I wanted to finish what I started without any additional libraries
> like itertools etc in the way that my knowledge allows. The idea with
> for this tuple just came up in a first seconds when I look at that
> and was not bothering about time or performance especially that later
> on as you seen I had different problem to solve and which took me quite
> a time and when I look at it today I think how couldn't I came with it
> earlier and let myself stuck on it.
>
> I'm happy that despite I've asked here I've finish it practically wthout
> additional help and yeah ( Thanks to Stefan who just pointed me to look
> at it from different prespective instead pointing what was wrong),
> I'll iterate here n = x [x for x in lil], with big string it can make
> difference. Now, when you asked me that question I came indeed for better
> idea to do this. One loop during which I can append character if not in lil.
>
>> How often does Tim's solution?
>
> oh here Im stuck and dont understand what you mean?

[Tim Chase]

> def consecutive_counter(seq):
> # I'm not sure if there's something
> # like this already in itertools
> cur = nada = object()
> count = 0
> for x in seq:
> if x == cur:
> count += 1
> else:
> if cur is not nada:
> yield cur, count
> cur = x
> count = 1
> if cur is not nada:
> yield cur, count
>
> def longest(seq):
> results = []
> biggest = 0
> for item, count in seq:
> if count > biggest:
> results = [item]
> biggest = count
> elif count == biggest:
> results.append(item)
> return results, biggest


Tim's code iterates over the string once whereas you iterate multiple
times. While this is mainly a question of elegance performance is
affected when you have *nested* loops:

> for i in lil:
> c = 0
> h= lil.index(i)
> for letter in s:

If you are unlucky and run into a string with 1000 different characters
the code in your inner loop will execute 1000*1000 times while Tim's
will run 1000 times. This is called O(N*N) and O(N).

Not all loops are obvious,

> lil.index(letter)

contains another loop, and you now have O(N*N*N) behavior.

This is the worst case, usually the alphabet (li1) will be smaller, but
avoiding nested loops when possible is still a good habit to get into.

--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
On 19/01/2021 10:42, Bischoop wrote:
> On 2021-01-19, Peter Otten <__peter__@web.de> wrote:
>> On 19/01/2021 04:45, Bischoop wrote:
>>
>>> I sat to it again and solved it.
>>
>> Congratulations!
>>
>>> lil = tuple(set(s)) # list of characters in s
>>>
>>> li=[0,0,0,0,0,0] # list for counted repeats
>>
>> I see a minor problem here. What happens if s contains more than len(li)
>> characters?
>>
>
> Thanks, I've created it when came to idea how to solve the problem and
> then forgot that part, will have to update it with two additional line
> of code.
>
>>> import timeit
>>
>> Since you seem interested in performance: imagine that the input is a
>> very long string. Let's call the length N.
>>
>> How often do you iterate over its characters?
>>
>
> Does it take time :-) I actually left it because seen guy in thread
> were comparing their time results, I'm pretty much aware that mine
> solution is time consuming and there are better ways to do it but
> I wanted to finish what I started without any additional libraries
> like itertools etc in the way that my knowledge allows. The idea with
> for this tuple just came up in a first seconds when I look at that
> and was not bothering about time or performance especially that later
> on as you seen I had different problem to solve and which took me quite
> a time and when I look at it today I think how couldn't I came with it
> earlier and let myself stuck on it.
>
> I'm happy that despite I've asked here I've finish it practically wthout
> additional help and yeah ( Thanks to Stefan who just pointed me to look
> at it from different prespective instead pointing what was wrong),
> I'll iterate here n = x [x for x in lil], with big string it can make
> difference. Now, when you asked me that question I came indeed for better
> idea to do this. One loop during which I can append character if not in lil.
>
>> How often does Tim's solution?
>
> oh here Im stuck and dont understand what you mean?

[Tim Chase]

> def consecutive_counter(seq):
> # I'm not sure if there's something
> # like this already in itertools
> cur = nada = object()
> count = 0
> for x in seq:
> if x == cur:
> count += 1
> else:
> if cur is not nada:
> yield cur, count
> cur = x
> count = 1
> if cur is not nada:
> yield cur, count
>
> def longest(seq):
> results = []
> biggest = 0
> for item, count in seq:
> if count > biggest:
> results = [item]
> biggest = count
> elif count == biggest:
> results.append(item)
> return results, biggest


Tim's code iterates over the string once whereas you iterate multiple
times. While this is mainly a question of elegance performance is
affected when you have *nested* loops:

> for i in lil:
> c = 0
> h= lil.index(i)
> for letter in s:

If you are unlucky and run into a string with 1000 different characters
the code in your inner loop will execute 1000*1000 times while Tim's
will run 1000 times. This is called O(N*N) and O(N).

Not all loops are obvious,

> lil.index(letter)

contains another loop, and you now have O(N*N*N) behavior.

This is the worst case, usually the alphabet (li1) will be smaller, but
avoiding nested loops when possible is still a good habit to get into.


--
https://mail.python.org/mailman/listinfo/python-list
Re: count consecutive elements [ In reply to ]
I'd wish to have this challenge posted on my blog but because I suck in
IT english, could you guys help me with decribing the task of what the
code supposed to do?

--
Thanks
--
https://mail.python.org/mailman/listinfo/python-list