Iterating Dictionaries in a Function

T

Thinker

I could not get this simple code work. I am guessing that there is a
bug
in the Python dictionary iterator.

def findx(st):
d = {'a': 1, 'rty': 4, 'er': 2}
for item in d.keys():
print item
if cmp(item.upper(),st.upper()) == 0:
print d[item]
return d[item]
else:
return st


When I call:
findx('a')
it finds the key. But when I call:
findx('er')
it does not find anything since it does not iterate; it just checks
the first item in the dictionary.

Does anyone see where the bug is?
 
M

Michael Geary

I could not get this simple code work. I am guessing that
there is a bug in the Python dictionary iterator.

def findx(st):
d = {'a': 1, 'rty': 4, 'er': 2}
for item in d.keys():
print item
if cmp(item.upper(),st.upper()) == 0:
print d[item]
return d[item]
else:
return st


When I call:
findx('a')
it finds the key. But when I call:
findx('er')
it does not find anything since it does not iterate; it just checks
the first item in the dictionary.

Does anyone see where the bug is?

Here's a tip: When I think there is a bug in Python (or C++, or whatever
language I'm using), sometimes there is. But usually the bug is in *my*
code. :)

In this code, your for loop always returns during the first iteration. This
is because you have return statements in both the if and else clauses, so
whether the if test succeeds or fails, the function returns immediately. The
loop never even looks at entries in the dict after the first one.

-Mike
 
R

Ryan Paul

I could not get this simple code work. I am guessing that there is a
bug
in the Python dictionary iterator.

def findx(st):
d = {'a': 1, 'rty': 4, 'er': 2}
for item in d.keys():
print item
if cmp(item.upper(),st.upper()) == 0:
print d[item]
return d[item]
else:
return st


When I call:
findx('a')
it finds the key. But when I call:
findx('er')
it does not find anything since it does not iterate; it just checks
the first item in the dictionary.

Does anyone see where the bug is?

its never going to make it past the first item, because you tell it to
return.

maybe you meant...?:

def findx(st):
d = {'a': 1, 'rty': 4, 'er': 2}
for item in d.keys():
print item
if item.upper() == st.upper():
print d[item]
return d[item]
return st

either way, looks like you should spend some time with the documentation.
 
M

Michael Geary

def findx(st):
d = {'a': 1, 'rty': 4, 'er': 2}
for item in d.keys():
print item
if cmp(item.upper(),st.upper()) == 0:
print d[item]
return d[item]
else:
return st

p.s. In my other message I explained the bug in your code. Now let's talk
about the design a bit. Generally, you're *much* better off if you can let
the dict itself handle the lookup rather than iterating through it yourself.
In a large dict this will be much faster.

It looks like you want to do a case-insensitive lookup in the dict. The way
to handle this would be to convert keys to uppercase or lowercase when you
enter them into the dict, and do the same with values that you look up.

Here's your test case modified to work this way:

def findx(st):
d = {'a': 1, 'rty': 4, 'er': 2}
try:
item = d[st.lower()]
except:
print 'Item not found:', st
else:
print 'Item found:', st, item
return item

findx('a')
findx('ER')
findx('foo')

Which prints:

Item found: a 1
Item found: ER 2
Item not found: foo

-Mike
 
J

John Hunter

Michael> It looks like you want to do a case-insensitive lookup in
Michael> the dict. The way to handle this would be to convert keys
Michael> to uppercase or lowercase when you enter them into the
Michael> dict, and do the same with values that you look up.

Or better yet, use the case insensitive dictionary recipe at

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66315

JDH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top