(Feb-09-2020, 04:14 AM)new_to_python Wrote: [ -> ]So am I correct that because 'Albert' and ['Alan', 'Adam'] are separated by ['Wes', 'Will'], 'Albert' is not consecutive to ['Alan', 'Adam'] and as a result, it forms its own group?
Python interactive interpreter is excellent tool for observing how stuff 'works':
>>> s = 'aabbc'
>>> itertools.groupby(s)
<itertools.groupby at 0x1187f9db0> # groupby object, not very helpful
>>> list(itertools.groupby(s)) # lets peek inside
[('a', <itertools._grouper at 0x118816ac8>), # groupby object is stream of tuples where:
('b', <itertools._grouper at 0x1188168d0>), - first element is group name
('c', <itertools._grouper at 0x118816940>)] - second element is group itself as grouper object
>>> for key, group in itertools.groupby(s): # Let's unpack it into human readable format
... print(f'Group name: {key}, group: {[*group]}')
...
Group name: a, group: ['a', 'a']
Group name: b, group: ['b', 'b']
Group name: c, group: ['c']
This is basic functionality which might seen not very helpful. But groupby supports key function which enables to do lot of interesting stuff. Some examples below.
Filter out numbers from user input/string:
>>> user_input = ' a34+ *2'
>>> for key, group in itertools.groupby(user_input, lambda char: char.isdigit()): # group based on type, key is bool i.e. True or False
... if key: # if group is True
... print(int(''.join(group)) # construct integer from list of strings which are digits
...
34
2
# as list comprehension one-liner:
>>> [int(''.join(group)) for key, group in itertools.groupby(user_input, lambda char: char.isdigit()) if key]
[34, 2]
Split on many splitters:
>>> text = 'abcdefghijklm'
>>> splitters = ['b','f','j'] # split text on these splitters
>>> list(''.join(group) for key, group in itertools.groupby(text, lambda split: split not in splitters) if key)
['a', 'cde', 'ghi', 'klm']
Combining with other itertools functions more 'interesting' code can be written.