Conversion from tuple to argument list?

mmillikan at vfa.com mmillikan at vfa.com
Wed Nov 21 22:58:54 CET 2001


David Bolen <db3l at fitlinxx.com> writes:
<snip>
> Thus the preface about "newer python releases".  This feature (and
> **kwargs for passing keyword arguments) mirrors the use of the similar
> syntax in function formal parameters for accepting normal unnamed and
> keyword arguments.  It was added in Python 2.0.
> 
> It's mentioned briefly in the What's New document for Python 2.0
> (http://www.python.org/2.0/new-python.html).  I'm not actually sure
> where it may be documented in the primary set of documentation.
> 
<snip>

Unpacking of sequences in function calls works when the sequence to
which the prefix '*' is applied is the last parameter:

>>> seqseq = ((1,2,3),('a','b','c'))
>>> seq = ('x','y','z')
>>> zip(seq,*seqseq)
[('x', 1, 'a'), ('y', 2, 'b'), ('z', 3, 'c')]

However, it doesn't work when the sequence to be unpacked is in any other
position in the parameter list:

>>> zip(*seqseq,seq)
  File "<stdin>", line 1
    zip(*seqseq,seq)
                  ^
SyntaxError: invalid syntax

Could this syntax be extended to allow the splicing to happen at any
position within the parameter list?

In the interim, the following module allows the construction:

>>> zip(*splice(unnest(seqseq),seq))
[(1, 'a', 'x'), (2, 'b', 'y'), (3, 'c', 'z')]

More elaborate splicing also appears to work:

>>> splice([10,20,30],[],unnest(['sam',unnest(unnest(['barney','fred']))]),seq,())
[[10, 20, 30], [], 'sam', 'barney', 'fred', ('x', 'y', 'z'), ()]

Only lightly tested, on 2.1.1

Feedback on utility and/or horrible flaws appreciated

------------------------------------------------------------------

#splice.py
from __future__ import nested_scopes

class unnest:
    
    def __init__(self,seq = []):
        if isinstance(seq,self.__class__):
            self.seq = seq
        else:
            self.seq = [item for item in seq]
            
    def items(self):
        return self.seq
    
    def __getitem__(self,index):
        if isinstance(self.seq,self.__class__):
            if index == 0:
                return self.seq
            else:
                raise IndexError
        else:
            return self.seq[index]
        
    def __len__(self):
        return len(self.seq)

def splice(*seqs):

    def _splice(flat,*seqs):
        unt = type(unnest())
        for seq in seqs:
            if seq:
                if type(seq) == unt:
                    items = seq.items()
                    if items and type(items[0]) == unt:
                        _splice(flat,seq.items())
                    else:
                        _splice(flat,*seq.items())
                else:
                    flat.append(seq)
            else:
                flat.append(seq)
        return flat
            
    return _splice([],*seqs)

Mark Millikan




More information about the Python-list mailing list