is there a better way?

Magnus Lycka lycka at carmen.se
Mon Feb 13 13:56:16 EST 2006


markscala at gmail.com wrote:
> Problem:
> 
> You have a list of unknown length, such as this: list =
> [X,X,X,O,O,O,O].  You want to extract all and only the X's.  You know
> the X's are all up front and you know that the item after the last X is
> an O, or that the list ends with an X.  There are never O's between
> X's.
> 
> I have been using something like this:
> _____________________
> 
> while list[0] != O:
>     storage.append(list[0])
>     list.pop(0)
>     if len(list) == 0:
>         break
> _____________________
> 
> But this seems ugly to me, and using "while" give me the heebies.  Is
> there a better approach?

It seems few suggested solutions actually do the same thing as
your code shows. I think this does. (Untested)

try:
     ix = aList.index(O)
     storage, aList = aList[:ix], aList[ix:]
except ValueError:
     # No O's
     storage, aList = aList, []


The main advantage with my approach over yours is that
all iterations, all the looping, takes place in fast C
code, unless your list elements are Python classes that
implement __cmp__ etc. If testing 'aList[0] == O'
involves Python, things might slow down a bit...

.index() takes linear time, but it's fairly fast. As
Alex suggested, you might want to replace it with a
O(log n) solution for big lists. You might need rather
big lists for the Python based O(log n) to get faster
than the C based O(n) though. Measure.



More information about the Python-list mailing list