[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

iterator/generator

vsoler

3/14/2010 5:18:00 PM

I am working on a script that reads data from an excel workbook. The
data is located in a named range whose first row contains the headers.
It works!!! I find it superb that python is able to do such things!!!

Now my questions.

a. My ranges can in practice be quite big, and although I am happy
with the speed I get, because I am learning python, I think I could do
it still a bit better. I think that the line for i in matriz[1:]:
could be improved with an iterator/generator, but I am not quite
certain how I should proceed.

b. the following lines could be improved by means of a defaultdict,
that I know because of a previous post. However you may come up with
some other ideas (this b. question is not my main concern, you may
discard it if you find the post too long)

if i[a] and not(i[a] in g) and i[b]:
g[i[a]] = i[b]
elif i[a] and (i[a] in g) and i[b]:
g[i[a]] += i[b]

Can anybody provide some hints? Thank you for your cooperation.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
import win32com.client as win32

def agrupar(matriz, c1, c2):
a, b = matriz[0].index(c1), matriz[0].index(c2)
g = {}
for i in matriz[1:]:
if i[a] and not(i[a] in g) and i[b]:
g[i[a]] = i[b]
elif i[a] and (i[a] in g) and i[b]:
g[i[a]] += i[b]
for k in g:
print '%-50s %15d' % (k, g[k])

# Abrir fichero excel
xl = win32.gencache.EnsureDispatch('Excel.Application')
##xl.Visible = True
wb=xl.Workbooks.Open(r'C:\Users\Vicente\Documents\VS\Python
\Presupuesto fijos 10YP 2011-2020 V0.xls')

# Obtención de datos
datos=wb.Names('Datos').RefersToRange()
print
agrupar(datos, u'NomCC', u'BGT-09')

# Cerrar libro de trabajo
wb.Close()
print
3 Answers

Steve Holden

3/14/2010 5:50:00 PM

0

vsoler wrote:
> I am working on a script that reads data from an excel workbook. The
> data is located in a named range whose first row contains the headers.
> It works!!! I find it superb that python is able to do such things!!!
>
> Now my questions.
>
> a. My ranges can in practice be quite big, and although I am happy
> with the speed I get, because I am learning python, I think I could do
> it still a bit better. I think that the line for i in matriz[1:]:
> could be improved with an iterator/generator, but I am not quite
> certain how I should proceed.
>
> b. the following lines could be improved by means of a defaultdict,
> that I know because of a previous post. However you may come up with
> some other ideas (this b. question is not my main concern, you may
> discard it if you find the post too long)
>
> if i[a] and not(i[a] in g) and i[b]:
> g[i[a]] = i[b]
> elif i[a] and (i[a] in g) and i[b]:
> g[i[a]] += i[b]
>
> Can anybody provide some hints? Thank you for your cooperation.
>
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +
> import win32com.client as win32
>
> def agrupar(matriz, c1, c2):
> a, b = matriz[0].index(c1), matriz[0].index(c2)
> g = {}
> for i in matriz[1:]:
> if i[a] and not(i[a] in g) and i[b]:
> g[i[a]] = i[b]
> elif i[a] and (i[a] in g) and i[b]:
> g[i[a]] += i[b]
> for k in g:
> print '%-50s %15d' % (k, g[k])
>
> # Abrir fichero excel
> xl = win32.gencache.EnsureDispatch('Excel.Application')
> ##xl.Visible = True
> wb=xl.Workbooks.Open(r'C:\Users\Vicente\Documents\VS\Python
> \Presupuesto fijos 10YP 2011-2020 V0.xls')
>
> # Obtención de datos
> datos=wb.Names('Datos').RefersToRange()
> print
> agrupar(datos, u'NomCC', u'BGT-09')
>
> # Cerrar libro de trabajo
> wb.Close()
> print

Before you go too far down this road (and congratulations, by the way,
on having achieved what you already have!) you might like to consider
the xlrd, xlwt and xlutils modules.

Not only are they easy to use, they are also (I believe) cross-platform
and do not require Excel to be loaded on the machine running the programs.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
See PyCon Talks from Atlanta 2010 http://pyco...
Holden Web LLC http://www.hold...
UPCOMING EVENTS: http://holdenweb.event...

Patrick Maupin

3/15/2010 2:08:00 AM

0

First of all, as Steve Holden mentioned, do look at xlrd. It's
awesome.

Second, for your (a) question, if you want an iterator, that's quite
easy:

matriz = iter(matriz)
matriz.next() # Discard the first one
for i in matriz:

This technique works really well, especially if you have sub-loops.
Then, if you use a defaultdict which uses a list for a constructor

for i in matriz:
if i[a] and i[b]:
g[i[a]].append(i[b])

HTH,
Pat

Mark Lawrence

3/15/2010 8:47:00 AM

0

vsoler wrote:
> I am working on a script that reads data from an excel workbook. The
> data is located in a named range whose first row contains the headers.
> It works!!! I find it superb that python is able to do such things!!!
>
> Now my questions.
>
> a. My ranges can in practice be quite big, and although I am happy
> with the speed I get, because I am learning python, I think I could do
> it still a bit better. I think that the line for i in matriz[1:]:
> could be improved with an iterator/generator, but I am not quite
> certain how I should proceed.

I write this :-
for j, i in enumerate(matriz):
if j:
etc...

If there's a better method for some definition of better I'm certain
we'll quickly get told.

Please see the python docs for the enumerate built-in.

HTH.

Mark Lawrence.

[snip the rest]