473,320 Members | 1,848 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

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

I'm writing some routines for handling dBASE files. I've got a table
(DBF file) object & field object already defined, and after opening the
file, I can get the field info like this:
tbl.Fields() [('STOCKNO', 'C', 8, 0), ('DACC', 'C', 5, 0), ('DEALERACCE', 'C', 30,
0), ('D-ACCRTL', 'C', 9, 0), ('D-ACCCST', 'C', 9, 0)]

What I would like to do is be able to extract the field names into a
single, separate list. It should look like:

['STOCKNO', 'DACC', 'DEALERACCE', 'D-ACCRTL', 'D-ACCCST']

but I'm not sure about how to do that. I can do this: for g in tbl.Fields(): print g[0]

....
STOCKNO
DACC
DEALERACCE
D-ACCRTL
D-ACCCST

but I expect that one of those fancy map/lamda/list comprehension
functions can turn this into a list for me, but, to be honest, they
still make my head spin trying to figure them out. Any ideas on how to
do this simply?
Even better yet... the reason I'm trying to do this is to make it easy
to refer to a field by the field name as well as the field number. I
expect to be reading all of the data into a list (1 per row/record) of
row objects. If someone wants to be able to refer to FldA in record 53,
then I'd like them to be able to use: "row[52].FldA" instead of having
to use "row[52][4]" (if it's the 5th field in the row). I was planning
on using the __getattr__ method in my row object like the following:

#----------------------------------------
def __getattr__(self,key):
""" Return by item name """
ukey = key.upper()
return self._data[tbl.FldNames.index(ukey)]
ukey = key.upper()

....where "tbl.FldNames" is the list of fieldnames that I'm trying to
build up above (and tbl is a property in the row pointing back to the
file object, since I don't want to make a copy of the fieldnames in
every row record). Is there a better (more efficient) way to go about
this? Thanks,

--
Greg

Jul 18 '05 #1
7 3817
Hello, Greg!
You wrote on Mon, 30 Jun 2003 19:44:20 -0500:

??>>>> tbl.Fields()
GB> [('STOCKNO', 'C', 8, 0), ('DACC', 'C', 5, 0), ('DEALERACCE', 'C', 30,

[Sorry, skipped]

GB> but I expect that one of those fancy map/lamda/list comprehension
GB> functions can turn this into a list for me, but, to be honest, they
GB> still make my head spin trying to figure them out. Any ideas on how to
GB> do this simply?

=============================================
a=[('STOCKNO', 'C', 8, 0), ('DACC', 'C', 5, 0), ('DEALERACCE', 'C', 30,
0), ('D-ACCRTL', 'C', 9, 0), ('D-ACCCST', 'C', 9, 0)]

b=[x[0] for x in a] # :-) Python is cool!

print b
=============================================

As I know the map/lamda/list works very slow and you should use it 'only'
with SCRIPTS.

[Sorry, skipped]

With best regards, Egor Bolonev. E-mail: eb******@rol.ru

Jul 18 '05 #2
"Egor Bolonev" <eb******@rol.ru> wrote in message
news:bd*********@news.rol.ru...
=============================================
a=[('STOCKNO', 'C', 8, 0), ('DACC', 'C', 5, 0), ('DEALERACCE', 'C', 30, 0), ('D-ACCRTL', 'C', 9, 0), ('D-ACCCST', 'C', 9, 0)]

b=[x[0] for x in a] # :-) Python is cool!

print b
=============================================

As I know the map/lamda/list works very slow and you should use it 'only' with SCRIPTS.


Thanks Egor!

It looks like I was closer than I thought - but still would have been
unlikely to figure it out!

--
Greg

Jul 18 '05 #3
Greg Brunet wrote:
but I'm not sure about how to do that. I can do this:
for g in tbl.Fields(): print g[0]


...
STOCKNO
DACC
DEALERACCE
D-ACCRTL
D-ACCCST

but I expect that one of those fancy map/lamda/list comprehension
functions can turn this into a list for me, but, to be honest, they
still make my head spin trying to figure them out. Any ideas on how to
do this simply?


fields = [
('STOCKNO', 'C', 8, 0),
('DACC', 'C', 5, 0),
('DEALERACCE', 'C', 30, 0),
('D-ACCRTL', 'C', 9, 0),
('D-ACCCST', 'C', 9, 0)
]

# The "old" way to do it would be:
NAME_COLUMN = 0
results = []
for field in fields:
results.append(field[NAME_COLUMN])
print results


# But list comprehensions are made for exactly this purpose
NAME_COLUMN = 0
results = [field[NAME_COLUMN] for field in fields]
print results
regards Max M

Jul 18 '05 #4
Greg Brunet wrote:

Even better yet... the reason I'm trying to do this is to make it easy
to refer to a field by the field name as well as the field number. I
expect to be reading all of the data into a list (1 per row/record) of
row objects. If someone wants to be able to refer to FldA in record 53,
then I'd like them to be able to use: "row[52].FldA" instead of having
to use "row[52][4]" (if it's the 5th field in the row). I was planning
on using the __getattr__ method in my row object like the following:

If that is all you want to do, this might be the simlest approach:

fields = [
('STOCKNO', 'C', 8, 0),
('DACC', 'C', 5, 0),
('DEALERACCE', 'C', 30, 0),
('D-ACCRTL', 'C', 9, 0),
('D-ACCCST', 'C', 9, 0)
]
def byName(field, name):
fieldNames = {
'name':0,
'letter':1,
'val1':2,
'val2':3,
}
return field[fieldNames[name]]
for field in fields:
print byName(field, 'name')
regards Max M

Jul 18 '05 #5
On Tue, 01 Jul 2003 10:03:11 +0200, Max M <ma**@mxm.dk> wrote:
Greg Brunet wrote:
but I'm not sure about how to do that. I can do this:
>for g in tbl.Fields(): print g[0]


...
STOCKNO
DACC
DEALERACCE
D-ACCRTL
D-ACCCST

but I expect that one of those fancy map/lamda/list comprehension
functions can turn this into a list for me, but, to be honest, they
still make my head spin trying to figure them out. Any ideas on how to
do this simply?


fields = [
('STOCKNO', 'C', 8, 0),
('DACC', 'C', 5, 0),
('DEALERACCE', 'C', 30, 0),
('D-ACCRTL', 'C', 9, 0),
('D-ACCCST', 'C', 9, 0)
]

# The "old" way to do it would be:
NAME_COLUMN = 0
results = []
for field in fields:
results.append(field[NAME_COLUMN])
print results


# But list comprehensions are made for exactly this purpose
NAME_COLUMN = 0
results = [field[NAME_COLUMN] for field in fields]
print results

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']

Regards,
Bengt Richter
Jul 18 '05 #6
>>>>> "Bengt" == Bengt Richter <bo**@oz.net> writes:
zip(*fields)


That is amazingly helpful. I've often needed to transpose a 2d list,
(mainly to get a "column" from an SQL query of a list of rows) and
this is just the trick.

I recently wrote a function to "deal" out a list of MySQLdb results,
where each field was a numeric type, and wanted to fill numeric arrays
with each column of results

With your trick, eg, for a list of results from three numeric fields,
I just have to do:

a1, a2, a3 = map(array, zip(*results))

John Hunter

Jul 18 '05 #7
"Bengt Richter" <bo**@oz.net> wrote in message
news:bd**********@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

Jul 18 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Tiffany Wilkes | last post by:
I solved the problem--I needed ( ) around the column list. I think the manual should make that more clear. -------- Original Message -------- Subject: column privilege problem Date: Tue, 05...
8
by: Vladimir | last post by:
Hello, I have a table in MS Access database. It has one field (with BYTE datatype) that has several properties set in Lookup tab of table Design View. Display Control = Combo Box. Row Source...
2
by: jobi | last post by:
Hi, I have this combobox which has a table from a dataset as datasource. When I click an item on the combobox-list , I would like to display (in textfield) the value from an other column that...
0
by: Brian Henry | last post by:
Here is another virtual mode example for the .NET 2.0 framework while working with the list view. Since you can not access the items collection of the list view you need to do sorting another...
4
by: shonend | last post by:
I am trying to extract the pattern like this : "SUB: some text LOT: one-word" Described, "SUB" and "LOT" are key words; I want those words, everything in between and one word following the...
6
by: Steve | last post by:
I realize that this probably isn't a best practice, but I'm working with legacy code that has a query stored in one column of a table. Because the queries vary, the JSP page that selects a query...
0
by: napolpie | last post by:
DISCUSSION IN USER nappie writes: Hello, I'm Peter and I'm new in python codying and I'm using parsying to extract data from one meteo Arpege file. This file is long file and it's composed by...
7
by: dmitrey | last post by:
howto make Python list from numpy.array? Thx, D.
1
by: malick | last post by:
Hello it developers, I'm using PHPExcelReader which I downloaded from sourceforge (http://sourceforge.net/projects/phpexcelreader) To read excel xls files in php. In the file reader.php (...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.