advice : how do you iterate with an acc ?

bonono at gmail.com bonono at gmail.com
Sat Dec 3 06:28:19 EST 2005


Bengt Richter wrote:
> On 2 Dec 2005 18:34:12 -0800, bonono at gmail.com wrote:
>
> >
> >Bengt Richter wrote:
> >> It looks to me like itertools.groupby could get you close to what you want,
> >> e.g., (untested)
> >Ah, groupby. The generic string.split() equivalent. But the doc said
> >the input needs to be sorted.
> >
>
>  >>> seq = [3,1,4,'t',0,3,4,2,'t',3,1,4]
>  >>> import itertools
>  >>> def condition(item): return item=='t'
>  ...
>  >>> def dosomething(it): return 'doing something with %r'%list(it)
>  ...
>  >>> for condresult, acciter in itertools.groupby(seq, condition):
>  ...     if not condresult:
>  ...         dosomething(acciter)
>  ...
>  'doing something with [3, 1, 4]'
>  'doing something with [0, 3, 4, 2]'
>  'doing something with [3, 1, 4]'
>
> I think the input only needs to be sorted if you a trying to group sorted subsequences of the input.
> I.e., you can't get them extracted together unless the condition is satisfied for a contiguous group, which
> only happens if the input is sorted. But AFAIK the grouping logic just scans and applies key condition
> and returns iterators for the subsequences that yield the same key function result, along with that result.
> So it's a general subsequence extractor. You just have to supply the key function to make the condition value
> change when a group ends and a new one begins. And the value can be arbitrary, or just toggle beween two values, e.g.
>
>  >>> for condresult, acciter in itertools.groupby(range(20), lambda x:x%3==0 or x==5):
>  ...     print '%6s: %r'%(condresult, list(acciter))
>  ...
>    True: [0]
>   False: [1, 2]
>    True: [3]
>   False: [4]
>    True: [5, 6]
>   False: [7, 8]
>    True: [9]
>   False: [10, 11]
>    True: [12]
>   False: [13, 14]
>    True: [15]
>   False: [16, 17]
>    True: [18]
>   False: [19]
>
> or a condresult that stays the same in groups, but every group result is different:
>
>  >>> for condresult, acciter in itertools.groupby(range(20), lambda x:x//3):
>  ...     print '%6s: %r'%(condresult, list(acciter))
>  ...
>       0: [0, 1, 2]
>       1: [3, 4, 5]
>       2: [6, 7, 8]
>       3: [9, 10, 11]
>       4: [12, 13, 14]
>       5: [15, 16, 17]
>       6: [18, 19]
>
Thanks. So it basically has an internal state storing the last
"condition" result and if it flips(different), a new group starts.




More information about the Python-list mailing list