Case-insensitive string compare?

Maric Michaud maric at aristote.info
Fri Sep 5 10:30:50 EDT 2008


Le Friday 05 September 2008 16:00:39 J. Cliff Dyer, vous avez écrit :
> Please keep the discussion on-list.
>

Sorry for the private email, I sent it again to the list..

> On Fri, 2008-09-05 at 15:36 +0200, Maric Michaud wrote:
> > Le Friday 05 September 2008 14:33:22 J. Clifford Dyer, vous avez écrit :
> > > On Thu, 2008-09-04 at 18:48 -0500, Robert Dailey wrote:
> > > > Thanks everyone for your help. I'm not opposed to using [key.lower()
> > > > for key in stage_map] at all, I was just curious to see if there were
> > > > any cleaner alternatives. It looks like that is what I'll be using.
> > > > I'm not familiar with how python works internally, but coming from
> > > > C++ it seems like "remaking" the map would be slow. However, speed is
> > > > not my main concern in my particular situation, I'm just curious to
> > > > learn more about python.
> > >
> > > You should be opposed to that particular solution.  You have just taken
> > > a dictionary lookup (very fast) and turned it into a list traversal
> > > (slow).  Even if speed isn't your main concern, this is an unnecessary
> > > de-optimization.  You are deliberately slowing down your program to
> > > avoid a slightly more verbose lookup later.  Your data structure might
> > > as well be a list of tuples to begin with, to avoid creating a new
> > > list. You have effectively made your keys useless as keys.
> > >
> > > If your lookups need to be case insensitive, make the key lower case,
> > > and store the cased version in the value, whether as a tuple or a dict
> > > (depending on whether you want named access).
> > >
> > > d = {
> > >    'foo': {'key': 'Foo', 'value': 'val1'}
> > >    'spam': {'key': 'sPAm', 'value': 'val2'}
> > > }
> > >
> > > search = 'FOO'.lower()
> > > if search in d:
> > >     result = d[search]
> > >     key = result['key']
> > >     value = result['value']
> > >
> > > The only reason I wouldn't use this solution is if you expect to have
> > > keys that will be identical when made lowercase, but if you're doing
> > > case-insensitive lookup, you obviously don't expect this to be an
> > > issue.
> >
> > The OP has already said the keys are case-sensitive, so this is not an
> > option, the only way to do it fast is to index upon insertion all keys in
> > another dict, so you get in final :
> > d = { "kEy1" : 1, "Key1" : 2}
> > indexes = { "key1" : ["kEy1", "Key1" ] }
>
> That does not get the same behavior as the OP's original solution.  The
> OP's solution retrieves the first matching value only.  Mine gets one
> arbitrary matching value, determined by the algorithm used for
> constructing the search dict (not specified in my solution).

string.lower() in indexes gives the same result, but your right, a set of 
lowered keys could suffice for the exact OP's requirement.

> What the 
> OP actually said was that he can't throw away the case.  You assume that
> this means there would be multiple entries distinguished only by case.
> That might be true, but given his initial solution, it seemed to me more
> likely that he wants to keep the case for display purposes, as in a
> dictionary like this:
>
> {
>    "Michaud": "Maric",
>    "Dyer": "Cliff",
>    "D'Amato": "Alphonse",
> }
>

I didn't want to make gratuitous extrapolations on the OP's data structure, 
but I still think the OP's question was "how to write cleanly a 
case-insensitive comparaison versus all the keys of a dict". Maybe I'm wrong.

--
_____________

Maric Michaud




More information about the Python-list mailing list