python - 忽略 Python 字符串中的大小写

标签 python string case-insensitive

在 Python 中忽略大小写比较字符串的最简单方法是什么?

当然可以执行 (str1.lower() <= str2.lower()) 等,但这会创建两个额外的临时字符串(具有明显的 alloc/g-c 开销)。

我想我正在寻找与 C 的 stricmp() 等效的方法。

[需要更多的上下文,所以我将用一个简单的例子来演示:]

假设你想对一个很长的字符串列表进行排序。您只需执行 List.sort()。 这是 O(n * log(n)) 字符串比较并且没有内存管理(因为所有 字符串和列表元素是某种智能指针)。你很开心。

现在,您也想这样做,但忽略大小写(让我们简化并说 所有字符串都是 ascii,因此可以忽略语言环境问题)。 你可以做 theList.sort(key=lambda s: s.lower()),但是你会导致两个新的 每次比较的分配,加上重复的垃圾收集器的负担 (降低)字符串。 每个这样的内存管理噪音都比简单的字符串比较慢几个数量级。

现在,使用类似 stricmp() 的就地函数,您可以执行以下操作:theList.sort(cmp=stricmp) 它与 theList.sort() 一样快速且内存友好。你又快乐了。

问题是任何基于 Python 的不区分大小写的比较都涉及隐式字符串 重复,所以我期待找到基于 C 的比较(可能在模块字符串中)。

找不到类似的东西,因此这里的问题。 (希望这可以澄清问题)。

最佳答案

这是一个基准,显示使用 str.lower比接受答案的建议方法(libc.strcasecmp)更快:

#!/usr/bin/env python2.7
import random
import timeit

from ctypes import *
libc = CDLL('libc.dylib') # change to 'libc.so.6' on linux

with open('/usr/share/dict/words', 'r') as wordlist:
    words = wordlist.read().splitlines()
random.shuffle(words)
print '%i words in list' % len(words)

setup = 'from __main__ import words, libc; gc.enable()'
stmts = [
    ('simple sort', 'sorted(words)'),
    ('sort with key=str.lower', 'sorted(words, key=str.lower)'),
    ('sort with cmp=libc.strcasecmp', 'sorted(words, cmp=libc.strcasecmp)'),
]

for (comment, stmt) in stmts:
    t = timeit.Timer(stmt=stmt, setup=setup)
    print '%s: %.2f msec/pass' % (comment, (1000*t.timeit(10)/10))

我机器上的典型时间:

235886 words in list
simple sort: 483.59 msec/pass
sort with key=str.lower: 1064.70 msec/pass
sort with cmp=libc.strcasecmp: 5487.86 msec/pass

因此,带有 str.lower 的版本不仅是迄今为止最快的,而且是这里提出的所有解决方案中最便携和最 Python 的。 我没有分析内存使用情况,但原始海报仍然没有给出令人信服的理由来担心它。另外,谁说对 libc 模块的调用不会复制任何字符串?

注意:lower() 字符串方法还具有依赖于语言环境的优点。在编写自己的“优化”解决方案时,您可能不会做对。即便如此,由于 Python 中的错误和缺失功能,这种比较可能会在 unicode 上下文中给出错误的结果。

关于python - 忽略 Python 字符串中的大小写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62567/

相关文章:

enums - JSON 模式枚举可以不区分大小写吗?

django-orm 不区分大小写的顺序

python - 在python中导入qt的问题

java - 空 Java 字符串的大小

python - 安装 django-templated-email

bash - 使用 bash 脚本解析字符串以获取最后一项

java - 最终引用变量的重要性

javascript - 使用 Underscore.js 进行不区分大小写的数组过滤

Python:构建一个由元组列表中的最小值组成的元组

python - 在 Python 中读取 ASCII 文件(numpy-array?)