python中不区分大小写的字符串类

python中不区分大小写的字符串类,python,string,python-2.7,case-insensitive,Python,String,Python 2.7,Case Insensitive,我需要在python中以集合和字典键执行不区分大小写的字符串比较。现在,创建不区分大小写的集合和dict子类被证明是非常棘手的(请参阅:对于想法,请注意它们都使用lower-嘿,甚至还有一个被拒绝的,尽管它的范围更广)。因此,我创建了一个不区分大小写的字符串类(利用@AlexMartelli的这一点): 代码基本上看起来不错。我会消除\uuuu ge\uuuuu、\uuu le\uuuuu和\uu ne\uuuuu中的捷径,并将它们展开以直接调用lower() 这条捷径看起来像是在'functo

我需要在python中以集合和字典键执行不区分大小写的字符串比较。现在,创建不区分大小写的集合和dict子类被证明是非常棘手的(请参阅:对于想法,请注意它们都使用lower-嘿,甚至还有一个被拒绝的,尽管它的范围更广)。因此,我创建了一个不区分大小写的字符串类(利用@AlexMartelli的这一点):


代码基本上看起来不错。我会消除
\uuuu ge\uuuuu
\uuu le\uuuuu
\uu ne\uuuuu
中的捷径,并将它们展开以直接调用lower()


这条捷径看起来像是在'functools.total_ordering()中完成的,但它只会减慢代码的速度,并使测试跨类型比较变得更加困难,而当方法相互依赖时,跨类型比较很难正确进行。

在演示中,您使用的是
'a'
来查找集合中的内容。如果您尝试使用
'A'
,它将不起作用,因为
'A'
具有不同的散列。另外,d.keys()中的
'A'将为true,但d中的
'A
将为false。实际上,您创建的类型违反了所有散列的正常约定,声称与具有不同散列的对象相等

您可以将此答案与关于创建专用dict的答案结合起来,并在尝试查找之前,将任何可能的键转换为
CIstr
。然后所有的
CIstr
转换都可以隐藏在dictionary类中

例如


(基于)

您确定需要上课吗?为什么不在需要时传递一个比较函数呢?或者存储stuff
lower
ed?@Karoly我需要原始字符串-传递comp函数会导致不太可维护的代码我会担心
CIstr
的实例声称与不等于它们的正常字符串相等,还有一个不同的哈希。@khelwood:有没有任何例子会导致行为不正常?@Mr_和Mrs_D:我不知道你在做什么,但为查找创建包装函数可能会解决可维护性问题,但这只是我的猜测。这是我最初的想法-但是以防弹的方式创建这样一个类会有很多复杂情况-所以即使是构造函数也会很棘手-什么是
CaseInsensitiveDict({'a':1})
yield?我假设您必须迭代给定dict中的项,并将每个键转换为您想要的形式。如果你想要与之不同的东西,那就由你自己来决定你的要求是什么。还想一想,这样的dict应该注意区分字符串和非字符串键我选择了包装dict-请看一看:)不幸的是,它会导致错误的行为(
'a'在d.keys()中)
vs
'A'in d
)-所以接受了@khelwood的答案-我不得不继续写下包装器命令:。欢迎评论:)
class CIstr(unicode):
    """Case insensitive with respect to hashes and comparisons string class"""

    #--Hash/Compare
    def __hash__(self):
        return hash(self.lower())
    def __eq__(self, other):
        if isinstance(other, basestring):
            return self.lower() == other.lower()
        return NotImplemented
    def __ne__(self, other): return not (self == other)
    def __lt__(self, other):
        if isinstance(other, basestring):
            return self.lower() < other.lower()
        return NotImplemented
    def __ge__(self, other): return not (self < other)
    def __gt__(self, other):
        if isinstance(other, basestring):
            return self.lower() > other.lower()
        return NotImplemented
    def __le__(self, other): return not (self > other)
d = {CIstr('A'): 1, CIstr('B'): 2}
print 'a' in d # True
s = set(d)
print {'a'} - s # set([])
class CaseInsensitiveDict(dict):
    def __setitem__(self, key, value):
        super(CaseInsensitiveDict, self).__setitem__(convert_to_cistr(key), value)
    def __getitem__(self, key):
        return super(CaseInsensitiveDict, self).__getitem__(convert_to_cistr(key))
    # __init__, __contains__ etc.