PEP 284, Integer for-loops (fwd)
Tim Peters
tim.one at comcast.net
Mon Mar 11 15:51:10 EST 2002
[James_Althoff at i2.com]
> ...
> But if your protocol is
> def getRowCount(): pass
> def getColumnCount(): pass
> def getValueAt(rowIndex,columnIndex): pass
> def setValueAt(rowIndex,columnIndex): pass
> then that option is not available.
Hmm. The inability to pass a new value to setValueAt seems to make this a
little feeble <wink>.
Depending on how much overhead you're willing to bear, it's straightfoward
to write wrapper classes (even using the old for/__getitem__ protocol) such
that, e.g., adding 1 to every element in a table could be expressed via
t = Table(original_table)
for r in t.rows():
for e in r.elements():
e.set(e.get() + 1)
Short of that, you could at least reduce the clumsiness by defining helper
functions, like (assuming these are 0-based indices; fiddle to taste):
def ri(table):
"Return row indices for table."
return range(table.getRowCount())
def ci(table):
"Return column indices for table."
return range(table.getColumnCount())
and then
columns = ci(table)
for i in ri(table):
for j in columns:
table.setValueAt(i, j, table.getValueAt(i, j) + 1)
would save some typing yet be just as quick. Add
def getter(table):
"Return bound table.GetValueAt."
return table.GetValueAt
def setter(table):
"Return bound table.SetValueAt."
return table.SetValueAt
and then
get, set = getter(table), setter(table)
columns = ci(table)
for i in ri(table):
for j in columns:
set(i, j, get(i, j) + 1)
would be about as fast as you can get in Python, short of defining a custom
"add 1 to element and then store it back" function.
If you're very concerned about speed, when you've got a choice the loop with
the largest trip count should be innermost (as true in Python as in any
other language, although this is clawing at what are usually third-order
effects).
More information about the Python-list
mailing list