Howto: extract a 'column' from a list of lists into a new list?

Greg Brunet gregbrunet at NOSPAMsempersoft.com
Tue Jul 1 23:20:06 EDT 2003


"Bengt Richter" <bokr at oz.net> wrote in message
news:bdspmf$leq$0 at 216.39.172.122...
> Or you can take advantage of zip:
>
>  >>> fields = [
>  ...      ('STOCKNO', 'C', 8, 0),
>  ...      ('DACC', 'C', 5, 0),
>  ...      ('DEALERACCE', 'C', 30, 0),
>  ...      ('D-ACCRTL', 'C', 9, 0),
>  ...      ('D-ACCCST', 'C', 9, 0)
>  ... ]
>  >>> zip(*fields)[0]
>  ('STOCKNO', 'DACC', 'DEALERACCE', 'D-ACCRTL', 'D-ACCCST')
>
> Or a list of all the columns of which only the first was selected
above:
>  >>> zip(*fields)
>  [('STOCKNO', 'DACC', 'DEALERACCE', 'D-ACCRTL', 'D-ACCCST'), ('C',
'C', 'C', 'C', 'C'), (8, 5, 30
>  , 9, 9), (0, 0, 0, 0, 0)]
>
> Since zip gives you a list of tuples, you'll have to convert if you
really need a list version
> of one of them:
>
>  >>> list(zip(*fields)[0])
>  ['STOCKNO', 'DACC', 'DEALERACCE', 'D-ACCRTL', 'D-ACCCST']

Bengt:

This looks great - but something isn't quite working for me.  If I type
in the stuff as you show, the zip function works, but if I use the
values that I get from my code, it doesn't.  Here's what I get in a
sample session:

#------------------------------------
>>> ff=dbf('nd.dbf')
>>> ff.Fields()
[('STOCKNO', 'C', 8, 0), ('DACC', 'C', 5, 0), ('DEALERACCE', 'C', 30,
0), ('D_ACCRTL', 'C', 9, 0), ('D_ACCCST', 'C', 9, 0), ('DEC', 'N', 10,
2)]
>>> zip(*ff.Fields())
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
TypeError: zip argument #1 must support iteration
#------------------------------------

Where the "dbf" invoices the _init_ for the dbf class which opens the
file & reads the header.  As part of that, the fields are placed in a
class variable, and accessed using the Fields() method.  At first I
wasn't sure of what the '*' did, but finally figured that out (section
5.3.4-Calls of the Language Reference for anyone else who's confused).

After puzzling it through a bit, I believe that Fields() is causing the
problem because it's not really a list of tuples as it appears.  Rather
it's a list of dbfField objects which have (among others) the following
2 methods:

class dbfField:
#----------------------------------------
    def __init__(self):
        pass

#----------------------------------------
    def create (self, fldName, fldType='C', fldLength=10, fldDec=0):
        # (lot's of error-checking omitted)
        self._fld = (fldName, fldType, fldLength, fldDec)
#----------------------------------------
    def __repr__(self):
        return repr(self._fld)
#----------------------------------------
    def __getitem__(self,key):
        """ Return by position or item name """
        if type(key) is IntType:
            return self._fld[key]
        elif type(key) is StringType:
            ukey = key.upper()
            if ukey=="NAME": return self._fld[0]
            elif ukey=="TYPE": return self._fld[1]
            elif ukey=="LENGTH": return self._fld[2]
            elif ukey=="DEC": return self._fld[3]


What I was trying to do, was to use the _fld tuple as the main object,
but wrap it with various methods & properties to 'safeguard' it.  Given
that can I still use zip to do what I want?  (Egor & Max's list
comprehension solution works fine for me, but the zip function seems
especially elegant)  I read in the library reference about iterator
types (sec 2.2.5 from release 2.2.2), and it looks like I could get it
to work by implementing the iterator protocol, but I couldn't find any
sample code to help in this.  Any idea if there's some available, or if
this is even worth it.

Better yet, is there a way for me to accomplish the same thing in a
simpler way?  It's likely that I'm 'brute-forcing' a solution that has
gotten to be a lot more complex than it needs to be.  Certainly if the
field definitions were in a simple tuple (which it is internally), zip
would work, but then it seems that I would lose the encapsulation
benefits.  Is there a way to achieve both?

Thanks again,

-- 
Greg





More information about the Python-list mailing list