在Python中比较字符串的最快方法

8 投票
10 回答
7488 浏览
提问于 2025-04-15 17:57

我正在用Python写一个脚本,用户可以输入一个字符串,这个字符串就是一个命令,告诉脚本要执行什么特定的操作。为了方便说明,我假设我的命令列表是:

lock
read
write
request
log

现在,我希望用户能够输入“log”,然后脚本就会执行一个特定的简单操作。不过,我还想让它能匹配部分单词。比如说,如果用户输入“lo”,它应该能匹配到“lock”,因为“lock”在列表中排得更前。我试过用ctypes从libc里调用strncmp来实现这个功能,但到现在还没搞明白怎么用。

10 个回答

3

这段代码在运行时进行了优化,正如你所要求的...(不过大概其实并不需要)

这里有一段简单的代码,它会接收一个字典,字典里是命令和对应的函数,然后输出一个新的字典,这个字典里包含了所有不重复的子命令,并且这些子命令都映射到同一个函数上。

所以你在启动服务的时候运行这段代码,这样你就可以实现100%优化的查找。我相信还有更聪明的方法可以做到这一点,所以欢迎你进行修改。

commands = {
  'log': log_function,
  'exit': exit_function,
  'foo': foo_function,
  'line': line_function,
  }

cmap = {}
kill = set()
for command in commands:
  for pos in range(len(1,command)):
    subcommand = command[0:pos]
    if subcommand in cmap:
      kill.add(subcommand)
      del(cmap[subcommand])
    if subcommand not in kill:
      cmap[subcommand] = commands[command]

#cmap now is the following - notice the duplicate prefixes removed?
{
  'lo': log_function,
  'log': log_function,
  'e': exit_function,
  'ex': exit_function,
  'exi': exit_function,
  'exit': exit_function,
  'f' : foo_function,
  'fo' : foo_function,
  'foo' : foo_function,
  'li' : line_function,
  'lin' : line_function,
  'line' : line_function,
}
5

这段代码可以实现你想要的功能:

def select_command(commands, user_input):
    user_input = user_input.strip().lower()
    for command in commands:
        if command.startswith(user_input):
            return command
    return None

不过:

你似乎对一些不重要的事情过于担心了。比如说,50个用户同时使用的话,延迟也就50毫秒——这种“卡顿”根本不会让你被赶出这个行业。你应该更关注数据库访问效率低下的问题,或者用户输入“r”时,系统返回“read”,而他们其实想要的是“request”。为了减少用户的输入而冒着出错的风险,这种想法就像是上世纪60年代的事情,真是让人哭笑不得。他们在用什么?ASR33打字机吗?至少你可以要求输入要有唯一性,比如“rea”代表“read”,“req”代表“request”。

16

如果你是在接收用户输入,那你为什么要担心比较的速度呢?即使是最慢的方法,也会比用户能感知到的速度快得多。尽量使用最简单、最容易理解的代码,把效率的问题留给那些需要频繁执行的核心部分去考虑。

cmds = [
    "lock",
    "read",
    "write",
    "request",
    "log",
    ]

def match_cmd(s):
    matched = [c for c in cmds if c.startswith(s)]
    if matched:
        return matched[0]

撰写回答