fastest way to compare strings in python

2019-04-22 23:33发布

I'm writing a script in Python that will allow the user to input a string, which will be a command that instructs the script to perform a specific action. For the sake of argument, I'll say my command list is:

lock
read
write
request
log

Now, I want the user to be able to enter the word "log" and it will peform a specific action, which is very simple. However, I would like to match partial words. So, for example, if a user enters "lo", it should match "lock", as it's higher in the list. I've tried using strncmp from libc using ctypes to accomplish this, but have yet to make heads or tails of it.

10条回答
Melony?
2楼-- · 2019-04-23 00:31

This will do what you want:

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

However:

You seem overworried about the wrong thing. So 50 users means 50 milliseconds -- you're not going to be run out of town for that kind of "lag". Worry about inefficient database access or problems caused by users typing "r" and getting "read" when they thought they'd get "request". Minimising user keystrokes at the risk of errors is so 1960s that it's not funny. What are they using? ASR33 teletypes? At the very least you could insist on a unique match -- "rea" for read and "req" for request.

查看更多
狗以群分
3楼-- · 2019-04-23 00:32

This is adapted from J.Tauber's Trie implementation in Python, which you could compare and/or re-adapt with whatever extra features you need. See also the Wikipedia entry on tries.

class Trie:
    def __init__(self):
        self.root = [None, {}]

    def add(self, key):
        curr_node = self.root
        for ch in key:
            curr_node = curr_node[1].setdefault(ch, [key, {}])
        curr_node[0] = key

    def find(self, key):
        curr_node = self.root
        for ch in key:
            try:
                curr_node = curr_node[1][ch]
            except KeyError:
                return None
        return curr_node[0]

Setup (order of addition matters!):

t = Trie()
for word in [
   'lock',
   'read',
   'write',
   'request',
   'log']:
   t.add(word)

Then call like this:

>>> t.find('lo')
'lock'
>>> t.find('log')
'log'
>>> t.find('req')
'request'
>>> t.find('requiem')
>>>
查看更多
beautiful°
4楼-- · 2019-04-23 00:33

I suggest you look at using the readline python library, rather than reinventing the wheel. The user will have to hit tab to complete the word, but you can set readline up so that tab matches as far as possible or cycles through all words starting wit the current stub.

This seems to be a fairly decent introduction to readline in python http://www.doughellmann.com/PyMOTW/readline/index.html

查看更多
该账号已被封号
5楼-- · 2019-04-23 00:34

you can use startswith

eg

myword = "lock"
if myword.startswith("lo"):
   print "ok"

or if you want to find "lo" in the word, regardless of position, just use the "in" operator

if "lo" in myword

therefore, one way you can do this:

for cmd in ["lock","read","write","request","log"]:
    if cmd.startswith(userinput):
        print cmd
        break
查看更多
登录 后发表回答