[Tutor] if string contains dictionary key

Wesley J. Chun wesc@alpha.ece.ucsb.edu
Thu, 10 Aug 2000 13:15:17 -0700 (PDT)


    > From: Daniel Yoo <dyoo@hkn.eecs.berkeley.edu>
    > Date: Thu, 10 Aug 2000 12:37:10 -0700 (PDT)
    > 
    > 'has', unfortunately, isn't a keyword.  You probably mean 'in' instead
    > 
    >   if s in d.keys():
    >     do stuff
    > 
    > Because 'in' does an exact check, 's' won't match with anything in 'd' in
    > your example.


this *would* work if 's' was 'CLR' or an actual key in the dictionary,
but unfortunately, that is not the case in steve's example.  the key
may be a *substring* of 's'.  in this case, you need to use one of the
string functions/methods to look within the string for the key.

but let's say that 's' *was* a potential key.  in this case, you can
use your example above:  "s in d.keys()".

However, performance pundits will probly raise some ire with that solu-
tion because it is much slower than:  "d.has_key(s)"

the reason being that first d.keys() has to go thru the entire set of
keys of the dictionary.  then it has to put them together, creating
a list.  when the list returns, a check would need to be made as to
whether 's' is in that list.  with has_key(), it just checks the keys
and says yes or no.

let's see this in action... here's a script called hasInTest.py:

#!/usr/bin/env python

import timeit

s = 'CLR'	# assume string can be a key now
d = {'CLR ': 'CLEAR', 'CA': 'ACCEPT', 'CR': 'CALL REQUEST'}

def doin(d, s):
    i = 0
    while i < 100000:
        s in d.keys()
        i = i + 1

def dohas(d, s):
    i = 0
    while i < 100000:
        d.has_key(s)
        i = i + 1

def main():
    timeit.timeit(doin, d, s)
    timeit.timeit(dohas, d, s)

if __name__ == '__main__':
    main()

- - - - - - - -

i wrote a script called timeit.py that just calls a function
and returns the time elapsed to run that function with arguments.

running this on a SPARC 5 with Solaris 2.7, you can see that it
takes more than 50% longer to use 'in' rather than 'has_key()':

% hasInTest.py
doin  0:9.11s
dohas 0:5.89s

let's try one more time:

% hasInTest.py
doin  0:9.08s
dohas 0:5.78s


basically, this is one of the cases where there is more than one
way of doing something in Python, and if there is, it's always
good to go over your code to see if you cna squeeze any more
precious run time out of it.

hope this helps!!

-wesley

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

"Core Python Programming", Prentice Hall PTR, TBP Fall 2000
    http://www.phptr.com/ptrbooks/ptr_0130260363.html

Python Books:   http://www.softpro.com/languages-python.html

wesley.j.chun :: wesc@alpha.ece.ucsb.edu
cyberweb.consulting :: silicon.valley, ca
http://www.roadkill.com/~wesc/cyberweb/