Fun with fancy slicing

Bengt Richter bokr at oz.net
Sat Oct 4 00:44:12 EDT 2003


On Fri, 03 Oct 2003 15:53:34 -0600, Fernando Perez <fperez528 at yahoo.com> wrote:

>Alex Martelli wrote:
>
>> How sweet it would be to be able to unpack by coding:
>>     head, *tail = alist
>
>+1000 :)
>
>I'd LOVE to have this syntax around.  I'd even want:
>
>head, *body, last = alist
>
>and 
>
>*head_and_body, last = alist
>
>to both work in their respectively obvious ways ;) (left-to-right unpacking,
>empty lists/tuples returned for elements which can't be unpacked --like if
>alist contains just one element, and the lhs returning tuple/list based on the
>type of the rhs).
>
>We can dream :)
>
Maybe spelling it a little differently wouldn't be too bad?
(tested only as you see ;-):

 >>> def headtail(seq): it=iter(seq); yield it.next(); yield list(it)
 ...
 >>> h,t = headtail(range(5))
 >>> h
 0
 >>> t
 [1, 2, 3, 4]
 >>> h,t
 (0, [1, 2, 3, 4])

Or from a generator

 >>> def g():
 ...     for i in range(0,100,10): yield i
 ...
 >>> h,t = headtail(g())
 >>> h,t
 (0, [10, 20, 30, 40, 50, 60, 70, 80, 90])

Not so useful:

 >>> h,t = headtail('abcd')
 >>> h,t
 ('a', ['b', 'c', 'd'])

Changes to list:

 >>> h,t = headtail( ('abc','123',1,2,3))
 >>> h
 'abc'
 >>> t
 ['123', 1, 2, 3]

So, to preserve common seq types, you could do a type-preserving-headtail

 >>> def tpheadtail(seq):
 ...     if isinstance(seq, str): yield seq[0]; yield seq[1:]; return
 ...     it = iter(seq); yield it.next()
 ...     if isinstance(seq, tuple): yield tuple(it)
 ...     else: yield list(it)
 ...
 >>> h,t = tpheadtail(range(5))
 >>> h,t
 (0, [1, 2, 3, 4])
 >>> h,t = tpheadtail(tuple(range(5)))
 >>> h,t
 (0, (1, 2, 3, 4))
 >>> h,t = tpheadtail('abcdef')
 >>> h,t
 ('a', 'bcdef')

You could control repacking ad libitum by adding a packing-format-control string parameter,
say '.' for one element, a decimal>1 for n elements in a tuple or list, one '*' for as many
elements as exist in the context, no prefix to preserve seq type, prefix T to make tuple,
L to make list. Hence the default headtail format would be '.*' -- some example spellings:

   h,t = repack(seq)          # head, *tail
   h,t = repack(seq, '*.')    # *head, tail
   h,m,t = repack(seq, '.*.') # head, *middle, last
   e1,e2,e3,tup,em2,em1 = repack(seq, '...t*..') # force seq[3:-2] to tuple for tup
   t5,myList123,restAsList = repack(seq, 'T5L123,L*')

This is a tangent from a prime number tangent from ... er, so the implementation of
the above will be left as an exercise ;-)

def repack(seq, fmt='.*'):
    # ... no ;-)












Regards,
Bengt Richter




More information about the Python-list mailing list