Rob,
That is a fairly straightforward and elegant solution if using an added mode called itertools.
I went a different way by creating my own focused iterator and calling it, when needed, to produce one or the other of the results requested in the functions named chunk() and chunkc(). But note my version operates to produce lists no matter what the input was. It produces lists nestled within lists. Presumably it could be adjusted to check if the input was a tuple and then return a grouping of tuples within a tuple.
The code, just for fun, is below and probably could be more elegant! LOL!
### CODE START
# Iterator version to be called as needed or all at once as with ChunkC
def ChunkIterator(seq):
# Purpose is to evaluate a list and return a list
# of lists with each one containing the longest run
# of each item.
# Handle an empty list
if len(seq) == 0: return container
# Initialize the first item in a copy.
# The first item is now in a initialized list.
gathered = [last := seq[0]]
# Loop over the remaining items and yield as needed.
for item in seq[1:]:
if len(gathered) == 0: gathered = [item]
elif item == last: gathered.append(item)
else: # not equal means yield result and start anew for next group
yield(gathered)
gathered = [last := item]
# After loop completes, any remaining data is returned as the function terminates.
if len(gathered) > 0: yield(gathered)
# Accesory function that runs the iterator to completion into a list.
def Chunk(seq): return list(ChunkIterator(seq))
# Function that simplifies the Chunks as an item and a number of instances.
def ChunkC(seq):
return [[group[0], len(group)] for group in ChunkIterator(seq)]
### CODE END
### EXAMPLES
tuple(Chunk([1, 2, 2, 'c', 'c', 'c', 'singleton']))
([1], [2, 2], ['c', 'c', 'c'], ['singleton'])
chunk([1, 2, 2, 'c', 'c', 'c', 'singleton'])
[[1], [2, 2], ['c', 'c', 'c'], ['singleton']]
chunkC([1, 2, 2, 'c', 'c', 'c', 'singleton'])
[[1, 1], [2, 2], ['c', 3], ['singleton', 1]]
# COMMENTS
The current version has flaws I have not bothered correcting. Just for a demo.
-----Original Message-----
From: Python-list <python-list-bounces+avi.e.gross=
gmail.com@python.org> On Behalf Of Rob Cliffe via Python-list
Sent: Monday, June 10, 2024 9:29 AM
To:
python-list@python.orgSubject: Re: in Python? -- Chunk -- (ChunkC '(a a b b b)), ==> ((a 2) (b 3))
import itertools
def chunk1(seq):
return [ ch * len(list(grp)) for (ch, grp) in itertools.groupby(s) ]
def chunk2(seq):
return [ (ch, len(list(grp))) for (ch, grp) in itertools.groupby(s) ]
s='aaabbccccaa'
print(chunk1(s))
print(chunk2(s))
###################################
Program output:
['aaa', 'bb', 'cccc', 'aa']
[('a', 3), ('b', 2), ('c', 4), ('a', 2)]
Rob Cliffe
On 09/06/2024 22:20, HenHanna via Python-list wrote:
>
Chunk, ChunkC -- nice simple way(s) to write these in Python?
>
>
(Chunk '(a a b a a a b b))
==> ((a a) (b) (a a a) (b b))
>
>
(Chunk '(a a a a b c c a a d e e e e))
==> ((a a a a) (b) (c c) (a a) (d) (e e e e))
>
>
(Chunk '(2 2 foo bar bar j j j k baz baz))
==> ((2 2) (foo) (bar bar) (j j j) (k) (baz baz))
>
_________________
>
(ChunkC '(a a b b b))
==> ((a 2) (b 3))
>
(ChunkC '(a a b a a a b b))
==> ((a 2) (b 1) (a 3) (b 2))
-- https://mail.python.org/mailman/listinfo/python-list