Algorithm help per favore

Alex Martelli aleax at aleax.it
Thu Jun 19 03:37:59 EDT 2003


Anton Vredegoor wrote:

> Alex Martelli <aleax at aleax.it> wrote:
> 
>>> [x for x, y in zip(L, [lambda x:x]+L) if x != y]
>>> 
>>> There must be a better way to do this than with a lambda.
> 
> <snip lambda>
> 
>>What about L[:1] + [x for x,y in zip(L[1:],L[:-1]) if x!=y] as
>>a less-tricky variant of your list-comprehension?  Does need L
>>to be a non-empty list (not another sequence, not an empty one),
>>but that might be acceptable perhaps...
> 
> Nice idea, there seems to be no problem with L an empty list, but
> there would be a problem with L a tuple. However that can be

RIght, an empty list gives no problems (the fail-soft feature of
slicing helps once again).  The simplest way to have this work
for a tuple as well as a list is clearly to change it to:

type(L)( list(L[:1]) + [x for x,y in zip(L[1:],L[:-1]) if x!=y] )

assuming you want the result to be the same type as L (if not,
just omit the type(L)( ... ) call around the core expression),
while, as I've seen pointed out in another post, your variant:

>    [x for x,y in zip(L,L[1:]+L[:-1]) if x!=y] or list(L[:1])

would erroneously omit the last element if it equals the first
one.  E.g., consider L == [3,2,3]; zip's arguments are then
[3,2,3] and [2,3]+[3,2] == [2,3,3,2] so zip's result is
[ (3,2), (2,3), (3,3) ] and the LC produces [3,2], erroneously
dropping the final 3.

In my version, I'm zipping [2,3] and [3,2], and concatenating
a leading [3] to the result, so no dropping occurs here.


Alex





More information about the Python-list mailing list