Fun with fancy slicing

Discussion in 'Python' started by Dave Benjamin, Sep 30, 2003.

  1. Hey all,

    I just realized you can very easily implement a sequence grouping function
    using Python 2.3's fancy slicing support:

    def group(values, size):
    return map(None, *[values[i::size] for i in range(size)])

    >>> group(range(20), 4)

    [(0, 1, 2, 3), (4, 5, 6, 7), (8, 9, 10, 11), (12, 13, 14, 15),
    (16, 17, 18, 19)]

    >>> group(range(14), 3)

    [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]

    I had to use map(None, *...) instead of zip(*...) to transpose the result
    because zip throws away the "orphans" at the end. Anyway, this is a useful
    function to have in your toolkit if you need to do pagination or
    multi-column display, among other things...

    Anyone have any other interesting applications of the extended slice syntax?

    Peace,
    Dave

    --
    ..:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
    : d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :
     
    Dave Benjamin, Sep 30, 2003
    #1
    1. Advertising

  2. Dave Benjamin <> writes:

    > Anyone have any other interesting applications of the extended slice syntax?


    You can use it in a sieve prime finder (ooh, thread crossing :):

    />> def sieve(p):
    |.. candidates = range(p)
    |.. for i in candidates[2:]:
    |.. if not candidates: continue
    |.. n = len(candidates[2*i::i])
    |.. candidates[2*i::i] = [0]*n
    |.. return filter(None, candidates[2:])
    \__
    ->> sieve(50)
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

    but it's not especially efficient (in speed or memory). Quite cute,
    though.

    Cheers,
    mwh

    --
    A typical luser can perform truly superhuman feats of strength &
    dexterity to avoid reading documentation. -- Lionel, asr
     
    Michael Hudson, Sep 30, 2003
    #2
    1. Advertising

  3. In article <>, Michael Hudson wrote:
    > Dave Benjamin <> writes:
    >
    >> Anyone have any other interesting applications of the extended slice syntax?

    >
    > You can use it in a sieve prime finder (ooh, thread crossing :):
    > ...
    > but it's not especially efficient (in speed or memory). Quite cute,
    > though.


    But quite expressive! I'm amazed at how small that code was. It reminds me
    of the trademark quicksort implementation in Haskell, ie. it may not be
    great in practice, but you can see the algorithm at a high level which makes
    it easier to figure out what's going on.

    Anyway, thanks. That was cool. =)

    Peace,
    Dave

    --
    ..:[ dave benjamin (ramenboy) -:- www.ramenfest.com -:- www.3dex.com ]:.
    : d r i n k i n g l i f e o u t o f t h e c o n t a i n e r :
     
    Dave Benjamin, Oct 1, 2003
    #3
  4. Dave Benjamin

    Gerrit Holl Guest

    Missing messagen (Was: Re: Fun with fancy slicing)

    Dave Benjamin wrote:
    > In article <>, Michael Hudson wrote:
    > > Dave Benjamin <> writes:
    > >
    > >> Anyone have any other interesting applications of the extended slice syntax?

    > >
    > > You can use it in a sieve prime finder (ooh, thread crossing :):
    > > ...
    > > but it's not especially efficient (in speed or memory). Quite cute,
    > > though.


    I do not seem to have received this message from Michael Hudson through
    python-list. I am able to locate it on the newsgroup. Does anyone else
    have this problem?

    Gerrit Holl.

    --
    278. If any one buy a male or female slave, and before a month has
    elapsed the benu-disease be developed, he shall return the slave to the
    seller, and receive the money which he had paid.
    -- 1780 BC, Hammurabi, Code of Law
    --
    Asperger Syndroom - een persoonlijke benadering:
    http://people.nl.linux.org/~gerrit/
    Het zijn tijden om je zelf met politiek te bemoeien:
    http://www.sp.nl/
     
    Gerrit Holl, Oct 1, 2003
    #4
  5. Dave Benjamin wrote:
    ...
    > of the trademark quicksort implementation in Haskell, ie. it may not be
    > great in practice, but you can see the algorithm at a high level which
    > makes it easier to figure out what's going on.


    Hmmm, you mean as in...:

    def quicksort(alist):
    head = alist[0]
    return quicksort([ x in alist[1:] if x<=head ]) + [
    head ] + quicksort([ x in alist[1:] if x>head ])

    ....?


    Alex
     
    Alex Martelli, Oct 1, 2003
    #5
  6. In article <ueEeb.206007$>,
    Alex Martelli <> wrote:

    > Dave Benjamin wrote:
    > ...
    > > of the trademark quicksort implementation in Haskell, ie. it may not be
    > > great in practice, but you can see the algorithm at a high level which
    > > makes it easier to figure out what's going on.

    >
    > Hmmm, you mean as in...:
    >
    > def quicksort(alist):
    > head = alist[0]
    > return quicksort([ x in alist[1:] if x<=head ]) + [
    > head ] + quicksort([ x in alist[1:] if x>head ])
    >
    > ...?


    Well, except that it gets a syntax error. And if you correct the syntax
    it gets an IndexError due to the lack of a base case for the recursion.
    And if you correct that, it still doesn't work correctly for lists with
    repeated items.

    How about:

    def quicksort(L):
    if len(L) < 2: return L
    return quicksort([x for x in L if x < L[0]]) + \
    [x for x in L if x == L[0]] + \
    quicksort([x for x in L if x > L[0]])

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science
     
    David Eppstein, Oct 1, 2003
    #6
  7. David Eppstein wrote:
    ...
    >> def quicksort(alist):
    >> head = alist[0]
    >> return quicksort([ x in alist[1:] if x<=head ]) + [
    >> head ] + quicksort([ x in alist[1:] if x>head ])

    >
    > Well, except that it gets a syntax error. And if you correct the syntax
    > it gets an IndexError due to the lack of a base case for the recursion.


    Right on both counts -- sorry.

    > And if you correct that, it still doesn't work correctly for lists with
    > repeated items.


    Why not? Having fixed the syntax and added the base-case, I see:

    [alex@lancelot perex]$ python -i se.py
    >>> import random
    >>> x=4*range(5)
    >>> random.shuffle(x)
    >>> x

    [4, 4, 3, 1, 1, 1, 1, 2, 0, 0, 3, 4, 3, 4, 2, 0, 3, 0, 2, 2]
    >>> quicksort(x)

    [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4]
    >>>


    So what am I missing? Please show a case of "list with repeated
    items" where the fixed quicksort "doesn't work correctly", thanks.

    btw, my favourite fixed version is:

    def quicksort(alist):
    try: head = alist[0]
    except IndexError: return alist
    return quicksort([ x for x in alist[1:] if x<=head ]) + [
    head ] + quicksort([ x for x in alist[1:] if x>head ])

    but I do see that testing len(alist) is probably better.

    How sweet it would be to be able to unpack by coding:
    head, *tail = alist
    ....


    Alex
     
    Alex Martelli, Oct 2, 2003
    #7
  8. In article <xdJeb.208403$>,
    Alex Martelli <> wrote:

    > David Eppstein wrote:
    > ...
    > >> def quicksort(alist):
    > >> head = alist[0]
    > >> return quicksort([ x in alist[1:] if x<=head ]) + [
    > >> head ] + quicksort([ x in alist[1:] if x>head ])

    > >
    > > Well, except that it gets a syntax error. And if you correct the syntax
    > > it gets an IndexError due to the lack of a base case for the recursion.

    >
    > Right on both counts -- sorry.
    >
    > > And if you correct that, it still doesn't work correctly for lists with
    > > repeated items.

    >
    > Why not? Having fixed the syntax and added the base-case, I see:


    Sorry, does work correctly, just not efficiently. I didn't see the = in
    the first recursive call. But if you call your quicksort on say [0]*n,
    each call will split the list as unevenly as possible and you get
    quadratic runtime. Of course we know that nonrandom quicksort pivoting
    can be quadratic anyway (e.g. on sorted input) but this to my mind is
    worse because randomization doesn't make it any better. The fact that
    some textbooks (e.g. CLRS!) make this mistake doesn't excuse it either.

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science
     
    David Eppstein, Oct 2, 2003
    #8
  9. Dave Benjamin

    Damien Wyart Guest

    * David Eppstein <> in comp.lang.python:
    > Of course we know that nonrandom quicksort pivoting can be quadratic
    > anyway (e.g. on sorted input) but this to my mind is worse because
    > randomization doesn't make it any better. The fact that some textbooks
    > (e.g. CLRS!) make this mistake doesn't excuse it either.


    Could you explain in more detail the error made in CLRS on this topic
    (with a reference if possible) ? I did not precisely catch your
    explanation here.

    Thanks in advance,
    --
    Damien Wyart
     
    Damien Wyart, Oct 2, 2003
    #9
  10. Re: Missing messagen (Was: Re: Fun with fancy slicing)

    Gerrit Holl <> writes:

    > Dave Benjamin wrote:
    > > In article <>, Michael Hudson wrote:
    > > > Dave Benjamin <> writes:
    > > >
    > > >> Anyone have any other interesting applications of the extended slice syntax?
    > > >
    > > > You can use it in a sieve prime finder (ooh, thread crossing :):
    > > > ...
    > > > but it's not especially efficient (in speed or memory). Quite cute,
    > > > though.

    >
    > I do not seem to have received this message from Michael Hudson through
    > python-list. I am able to locate it on the newsgroup. Does anyone else
    > have this problem?


    Hmm, I saw it :)

    Google also has it:

    http://groups.google.com/groups?selm=

    I don't really read the newsgroup closely enough any more to know if
    any messages are going missing, I'm afraid.

    Cheers,
    mwh


    --
    Screaming 14-year-old boys attempting to prove to each other that
    they are more 3133t than j00.
    -- Reason #8 for quitting slashdot today, from
    http://www.cs.washington.edu/homes/klee/misc/slashdot.html
     
    Michael Hudson, Oct 2, 2003
    #10
  11. In article <3f7bf423$0$20654$>,
    Damien Wyart <> wrote:

    > * David Eppstein <> in comp.lang.python:
    > > Of course we know that nonrandom quicksort pivoting can be quadratic
    > > anyway (e.g. on sorted input) but this to my mind is worse because
    > > randomization doesn't make it any better. The fact that some textbooks
    > > (e.g. CLRS!) make this mistake doesn't excuse it either.

    >
    > Could you explain in more detail the error made in CLRS on this topic
    > (with a reference if possible) ? I did not precisely catch your
    > explanation here.
    >
    > Thanks in advance,


    CLRS' partition routine ends up partitioning an n-item array into the
    items <= the pivot, the pivot itself, and the items > the pivot.
    If the items are all equal, that means that the first part gets n-1
    items and the last part gets nothing, regardless of which item you
    select as pivot. If you analyze the algorithm on this input, you get
    the recurrence T(n)=O(n)+T(n-1)+T(0) which solves to O(n^2).

    Throughout most of the quicksort chapter, CLRS at least include
    exercises mentioning the case of all equal inputs, asking what happens
    for those inputs, and in one exercise suggesting a partition routine
    that might partition those inputs more equally (but who knows what it
    should do when merely most of the inputs are equal...) However in the
    randomized quicksort section they ignored this complication and seemed
    to be claiming that their randomized quicksort has O(n log n) expected
    time, unconditionally.

    This problem was finally corrected in the fourth printing of the second
    edition; see the errata at
    <http://www.cs.dartmouth.edu/~thc/clrs-2e-bugs/bugs.php>
    for more details.

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science
     
    David Eppstein, Oct 2, 2003
    #11
  12. Dave Benjamin

    David C. Fox Guest

    Re: *-unpacking (Re: Fun with fancy slicing)

    Greg Ewing (using news.cis.dfn.de) wrote:
    > Alex Martelli wrote:
    >
    >> How sweet it would be to be able to unpack by coding:
    >> head, *tail = alist

    >
    >
    > Indeed! I came across another use case for this
    > recently, as well. I was trying to parse some
    > command strings of the form
    >
    > command arg arg ...
    >
    > where some commands had args and some didn't.
    > I wanted to split the command off the front
    > and keep the args for later processing once
    > I'd decoded the command. My first attempt
    > went something like
    >
    > command, args = cmdstring.split(" ", maxsplit = 1)
    >
    > but this fails when there are no arguments,
    > because the returned list has only one element
    > in that case.
    >
    > It would have been very nice to be able to
    > simply say
    >
    > command, *args = cmdstring.split()
    >
    > and get the command as a string and a
    > list of 0 or more argument strings.
    >
    > I really ought to write a PEP about this...
    >


    In the mean time, it isn't too hard to write a function which does this:

    def first_rest(x):
    return x[0], x[1:]

    command, args = first_rest(cmdstring.split())

    or, in one step

    def chop_word(s):
    return first_rest(s.split())

    command, args = chop_word(cmdstring)

    David
     
    David C. Fox, Oct 3, 2003
    #12
  13. Re: *-unpacking

    |Alex Martelli wrote:
    |> How sweet it would be to be able to unpack by coding:
    |> head, *tail = alist

    "Greg Ewing (using news.cis.dfn.de)" <> wrote previously:
    | command arg arg ...
    | command, *args = cmdstring.split()
    |and get the command as a string and a list of 0 or more argument strings.

    I think I've written on this list before that I would like this
    too--Ruby does this, IIRC. If anyone writes a PEP, you have my +1 in
    advance.

    For Greg's particular case, one approach that doesn't look too bad is:

    command = args.pop(0)
    # ... do stuff ...
    try:
    more = args.pop(0)
    except IndexError:
    # no more

    For a really long list, it would be faster to do an 'args.reverse()' up
    front, and '.pop()' off the end (Greg and Alex know all this, of course).

    Yours, Lulu...

    --
    mertz@ _/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY: \_\_\_\_ n o
    gnosis _/_/ Postmodern Enterprises \_\_
    ..cx _/_/ \_\_ d o
    _/_/_/ IN A WORLD W/O WALLS, THERE WOULD BE NO GATES \_\_\_ z e
     
    Lulu of the Lotus-Eaters, Oct 3, 2003
    #13
  14. *-unpacking (Re: Fun with fancy slicing)

    Alex Martelli wrote:
    > How sweet it would be to be able to unpack by coding:
    > head, *tail = alist


    Indeed! I came across another use case for this
    recently, as well. I was trying to parse some
    command strings of the form

    command arg arg ...

    where some commands had args and some didn't.
    I wanted to split the command off the front
    and keep the args for later processing once
    I'd decoded the command. My first attempt
    went something like

    command, args = cmdstring.split(" ", maxsplit = 1)

    but this fails when there are no arguments,
    because the returned list has only one element
    in that case.

    It would have been very nice to be able to
    simply say

    command, *args = cmdstring.split()

    and get the command as a string and a
    list of 0 or more argument strings.

    I really ought to write a PEP about this...

    --
    Greg Ewing, Computer Science Dept,
    University of Canterbury,
    Christchurch, New Zealand
    http://www.cosc.canterbury.ac.nz/~greg
     
    Greg Ewing (using news.cis.dfn.de), Oct 3, 2003
    #14
  15. Re: *-unpacking (Re: Fun with fancy slicing)

    In article <Jd7fb.484435$cF.170532@rwcrnsc53>,
    "David C. Fox" <> wrote:

    > In the mean time, it isn't too hard to write a function which does this:
    >
    > def first_rest(x):
    > return x[0], x[1:]


    Shouldn't that be called cons?

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science
     
    David Eppstein, Oct 3, 2003
    #15
  16. Re: *-unpacking (Re: Fun with fancy slicing)

    David Eppstein wrote:

    >> In the mean time, it isn't too hard to write a function which does this:
    >>
    >> def first_rest(x):
    >> return x[0], x[1:]

    >
    > Shouldn't that be called cons?


    Hmmm, feels more like the 'reverse' of a cons to me -- takes a list
    and gives me the car and cdr...


    Alex
     
    Alex Martelli, Oct 3, 2003
    #16
  17. Re: *-unpacking

    Lulu of the Lotus-Eaters wrote:
    ...
    > |> head, *tail = alist
    >
    > "Greg Ewing (using news.cis.dfn.de)" <> wrote
    > previously:
    > | command arg arg ...
    > | command, *args = cmdstring.split()
    > |and get the command as a string and a list of 0 or more argument strings.
    >
    > I think I've written on this list before that I would like this
    > too--Ruby does this, IIRC. If anyone writes a PEP, you have my +1 in
    > advance.
    >
    > For Greg's particular case, one approach that doesn't look too bad is:
    >
    > command = args.pop(0)
    > # ... do stuff ...
    > try:
    > more = args.pop(0)
    > except IndexError:
    > # no more


    I'm not sure what this 'more' is about, actually. Greg's case is
    currently best solved [IMHO] with
    args = cmdstring.split()
    command = args.pop(0)

    > For a really long list, it would be faster to do an 'args.reverse()' up
    > front, and '.pop()' off the end (Greg and Alex know all this, of course).


    Actually, I don't -- both args.reverse() and args.pop(0) are O(len(args)),
    so I don't know their relative speeds offhand. Interestingly enough,
    timeit.py, for once, doesn't want to let me know about them either...:

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags.pop(0)'
    Traceback (most recent call last):
    File "timeit.py", line 249, in main
    x = t.timeit(number)
    File "timeit.py", line 158, in timeit
    return self.inner(it, self.timer)
    File "<timeit-src>", line 6, in inner
    x=ags.pop(0)
    IndexError: pop from empty list
    [alex@lancelot python2.3]$

    ....since each .pop is modifying the ags list, the once-only setup
    statement doesn't suffice... OK, so we need to repeat (and thus,
    alas, intrinsically measure) the list copying too (sigh):

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24.5 usec per loop

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'ags.reverse(); x=ags[:].pop()'
    10000 loops, best of 3: 23.2 usec per loop

    the results of the two snippets aren't identical, but that should
    not affect the timing measured (as the use of ags[:] and the
    repetition are time-measurement artefacts anyway). So, it does
    look like reversing first IS faster -- by a hair. Trying to
    remove the ags[:] part / overhead gave me a shock, though...:

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    10000 loops, best of 3: 35.2 usec per loop

    So -- it's clear to me that I do NOT understand what's going on
    here. If just the ags[:] is 35.2 usec, how can the ags[:].pop(0)
    be 24.5 ... ???

    Tim...? Please HELP a fellow bot in need...!!!


    Alex
     
    Alex Martelli, Oct 3, 2003
    #17
  18. Re: *-unpacking

    Alex Martelli <> writes:

    > So -- it's clear to me that I do NOT understand what's going on
    > here. If just the ags[:] is 35.2 usec, how can the ags[:].pop(0)
    > be 24.5 ... ???


    How quiet was your machine when you ran the tests? I see behaviour
    more in line with what you'd expect:

    [mwh@pc150 build]$ ./python ../Lib/timeit.py -s'ags=range(1000)' 'x=ags[:]'
    10000 loops, best of 3: 31.6 usec per loop
    [mwh@pc150 build]$ ./python ../Lib/timeit.py -s'ags=range(1000)' 'x=ags[:].pop(0)'
    10000 loops, best of 3: 39.8 usec per loop

    Cheers,
    mwh

    --
    About the use of language: it is impossible to sharpen a
    pencil with a blunt axe. It is equally vain to try to do
    it with ten blunt axes instead.
    -- E.W.Dijkstra, 18th June 1975. Perl did not exist at the time.
     
    Michael Hudson, Oct 3, 2003
    #18
  19. Re: *-unpacking (Re: Fun with fancy slicing)

    In article <22cfb.159311$>,
    Alex Martelli <> wrote:

    > David Eppstein wrote:
    >
    > >> In the mean time, it isn't too hard to write a function which does this:
    > >>
    > >> def first_rest(x):
    > >> return x[0], x[1:]

    > >
    > > Shouldn't that be called cons?

    >
    > Hmmm, feels more like the 'reverse' of a cons to me -- takes a list
    > and gives me the car and cdr...


    Well, but it returns an object composed of a car and a cdr, which is
    exactly what a cons is...

    --
    David Eppstein http://www.ics.uci.edu/~eppstein/
    Univ. of California, Irvine, School of Information & Computer Science
     
    David Eppstein, Oct 3, 2003
    #19
  20. Re: *-unpacking

    Michael Hudson wrote:

    > Alex Martelli <> writes:
    >
    >> So -- it's clear to me that I do NOT understand what's going on
    >> here. If just the ags[:] is 35.2 usec, how can the ags[:].pop(0)
    >> be 24.5 ... ???

    >
    > How quiet was your machine when you ran the tests? I see behaviour


    Very, and the numbers were highly repeatable:

    -- running just now:

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    10000 loops, best of 3: 36.9 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    10000 loops, best of 3: 35.2 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    10000 loops, best of 3: 35.8 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    10000 loops, best of 3: 35.6 usec per loop

    -- and from a copy & paste of the screen as of a while ago:

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24.5 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24.5 usec per loop

    -- _however_ -- retrying the latter now:

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 48.8 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 46.1 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 46.5 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24.5 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24.4 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24.5 usec per loop

    -- _SO_ -- immediately going back to the just-copy tests...:

    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    100000 loops, best of 3: 19.3 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    100000 loops, best of 3: 19.3 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -s'ags=range(1000)' 'x=ags[:]'
    100000 loops, best of 3: 19.3 usec per loop


    SO -- so much for the "quiet"... clearly there _IS_ something periodically
    running and distorting the elapsed-time measurements (which are the default
    here on Linux) by a hefty factor of 2. So much for this kind of casual
    benchmarking...!-) I guess I've been doing a little too much of it...


    > more in line with what you'd expect:
    >
    > [mwh@pc150 build]$ ./python ../Lib/timeit.py -s'ags=range(1000)'
    > ['x=ags[:]'
    > 10000 loops, best of 3: 31.6 usec per loop
    > [mwh@pc150 build]$ ./python ../Lib/timeit.py -s'ags=range(1000)'
    > ['x=ags[:].pop(0)'
    > 10000 loops, best of 3: 39.8 usec per loop


    Yep, makes more sense. So, moving to the more-stable -c (CPU time,
    as given by time.clock):

    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:]'
    100000 loops, best of 3: 19.2 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:]'
    100000 loops, best of 3: 19.2 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:]'
    100000 loops, best of 3: 19.2 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 24 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'x=ags[:].pop(0)'
    10000 loops, best of 3: 23 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'ags.reverse(); x=ags[:].pop()'
    10000 loops, best of 3: 23 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'ags.reverse(); x=ags[:].pop()'
    10000 loops, best of 3: 22 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'ags.reverse(); x=ags[:].pop()'
    10000 loops, best of 3: 23 usec per loop
    [alex@lancelot python2.3]$ python timeit.py -c -s'ags=range(1000)'
    'ags.reverse(); x=ags[:].pop()'
    10000 loops, best of 3: 23 usec per loop

    it WOULD seem to be confirmed that reverse-then-pop() is VERY
    slightly faster than pop(0) -- 22/23 instead of 23/24 usec for
    a 1000-long list... of which 19.2 are the apparently-repeatable
    overhead of copying that list. I still wouldn't say that I
    "KNOW" this, though -- the margin is SO tiny and uncertain...!!!

    It seems to scale up linearly going from 1000 to 5000: just
    the copy, 105-108; ags[:].pop(0), 120-123; reverse then pop,
    116-117. This is always with the -c (once burned...).


    Alex
     
    Alex Martelli, Oct 3, 2003
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. steven robinson
    Replies:
    10
    Views:
    1,097
    Tim Tyler
    Nov 27, 2003
  2. Andy Fish
    Replies:
    65
    Views:
    1,813
    Mabden
    May 18, 2004
  3. Ramon F Herrera

    Can Java do fancy GUIs?

    Ramon F Herrera, Apr 16, 2005, in forum: Java
    Replies:
    56
    Views:
    1,665
    Thomas G. Marshall
    Apr 23, 2005
  4. dolphin
    Replies:
    4
    Views:
    333
    Jorgen Grahn
    Aug 25, 2007
  5. er
    Replies:
    2
    Views:
    535
Loading...

Share This Page