"Collapsing" a list into a list of changes

Nick Coghlan ncoghlan at iinet.net.au
Fri Feb 4 23:28:15 EST 2005


John J. Lee wrote:
> Steven Bethard <steven.bethard at gmail.com> writes:
> 
> 
>>Mike C. Fletcher wrote:
> 
> [...]
> 
>>> >>> def changes( dataset ):
>>>...     last = None
>>>...     for value in dataset:
>>>...         if value != last:
>>>...             yield value
>>>...         last = value
>>>...        >>> print list(changes(data ))
>>>which is quite readable/elegant IMO.
>>
>>But fails if the list starts with None:
>>
>>py> lst = [None,0,0,1,1,1,2,2,3,3,3,2,2,2,4,4,4,5]
>>py> def changes(dataset):
>>...     last = None
>>...     for value in dataset:
>>...         if value != last:
>>...             yield value
>>...         last = value
>>...
>>py> list(changes(lst))
>>[0, 1, 2, 3, 2, 4, 5]
>>
>>A minor modification that does appear to work:
>>
>>py> def changes(dataset):
>>...     last = object()
>>...     for value in dataset:
>>...         if value != last:
>>...             yield value
>>...         last = value
>>...
>>py> list(changes(lst))
>>[None, 0, 1, 2, 3, 2, 4, 5]
> 
> 
> Unless the first object in the list has a weird __cmp__ (does
> happen...).  OK, weird __cmp__s are nasty anyway, but still, why
> compound it through cleverness when you can write a really plodding
> function that *always* does what it says on the tin?

In that case:

Py> def collapsed(iterable):
...   itr = iter(iterable)
...   last = itr.next()
...   yield last
...   for value in itr:
...     if value != last:
...       yield value
...       last = value
...
Py> from Tkinter import _flatten #**
Py> lst = list(_flatten([[i] * 5 for i in range(10)]))
Py> lst
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5
, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9]
Py> list(collapsed(lst))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

** Hmm, this function really is quite handy when generating test data. Maybe in 
Python 2.5 the line should be spelt "from itertools import flatten"

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net



More information about the Python-list mailing list