[Tutor] Finding which list entry is being used, in a for loop
Kent Johnson
kent37 at tds.net
Fri May 20 02:22:58 CEST 2005
Terry Carroll wrote:
> On Tue, 17 May 2005, Kent Johnson wrote:
>
>
>>I often find that the information in the traceback and exception are
>>enough to figure out the problem; if not, a few print statements can
>>help. You will get better at this with experience.
>
>
> Here's an example where traceback and print statements doesn't help, and
> it's really nice to have access to the variables...
>
> Suppose I have a long list of lists (by "long," I mean, too long to
> display on one screen and visually examine easily), and am iterating over
> the inner lists. (Forget whether there might be more
> efficient ways;
> this is just for illustration.)
>
> In most languages, you'd take this unpythonic approach:
>
> for i in range(0,len(mylist)):
> for j in range(0, len(mylist[i])):
> # stuff dependent on mylist[i][j]
>
> I could put in "print i,j, mylist[i][j]" statements in here, and pretty
> easily zero in on the exceptional data.
>
> But a pythonic approach, and the one I find easiest, is:
>
> for innerlist in mylist:
> for item in innerlist:
> # stuff dependent on item
>
> Now, I can only put in "print item", and finding that in the nested list
> is like a needle in a haystack. That's what I like about the -i
> option... I can use Python expressions to iterate through the list
> lookingfor stuff.
>
> Is there any way, in the second construct, to have the traceback (or
> equivalent info) include where in "innerlist" "item" came from, and where
> in "mylist" "innerlist" came from?
OK, you have prompted me to play around with the recipe I cited earlier. Here is a version that
looks promising to me. I have this in Python24\Lib\site-packages\debug_helper.py:
###
import sys, traceback
def print_exc_plus_hook(type, value, tb):
"""
Print the usual traceback information, followed by a listing of all the
local variables in the current frame.
Based on this recipe: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52215
"""
if not tb or issubclass(type, SyntaxError):
sys.__excepthook__(type, value, tb)
return
traceback.print_exception(type, value, tb)
while 1:
if not tb.tb_next:
break
tb = tb.tb_next
frame = tb.tb_frame
# Try to filter out top-level command line errors
if frame.f_locals.has_key('__builtins__'):
return
print >> sys.stderr
print >> sys.stderr, "Frame %s in %s at line %s" % (frame.f_code.co_name,
frame.f_code.co_filename,
frame.f_lineno)
for key, value in frame.f_locals.items():
print >> sys.stderr, "\t%20s = " % key,
#We have to be careful not to cause a new error in our error
#printer! Calling repr() on an unknown object could cause an
#error we don't want.
try:
print >> sys.stderr, repr(value)
except:
print >> sys.stderr, "<ERROR WHILE PRINTING VALUE>"
def install_excepthook():
sys.excepthook = print_exc_plus_hook
###
Then I created a file Python24\Lib\site-packages\sitecustomize.py containing these few lines:
# Install an exception handler that prints the current stack frame
from debug_helper import install_excepthook
install_excepthook()
###
Now when I get an exception the usual stack trace prints plus the values of the local variables. (I
took out the printing of the variables in the higher stack frames, that seems like overkill to me.
So in your example, when an exception occurs, you would get a printout with the values of innerlist
and item which are both variables in the local scope. If you want more, you could temporarily change
the list to
for i, innerlist in enumerate(mylist):
for j, item in enumerate(innerlist):
# stuff dependent on item
then you will get the indices as well.
I'm going to try this out and see I find it helpful...
Kent
More information about the Tutor
mailing list