*-unpacking

Alex Martelli aleax at aleax.it
Fri Oct 3 12:34:50 EDT 2003


Lulu of the Lotus-Eaters wrote:
   ...
> |>     head, *tail = alist
> 
> "Greg Ewing (using news.cis.dfn.de)" <g2h5dqi002 at sneakemail.com> 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 at 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 at 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 at 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 at 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 at 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







More information about the Python-list mailing list