How can I optimize this Python code to generate all words with word-distance 1?

前端 未结 12 836
予麋鹿
予麋鹿 2021-01-30 22:11

Profiling shows this is the slowest segment of my code for a little word game I wrote:

def distance(word1, word2):
    difference = 0
    for i in range(len(word         


        
12条回答
  •  抹茶落季
    2021-01-30 22:19

    Your function distance is calculating the total distance, when you really only care about distance=1. The majority of cases you'll know it's >1 within a few characters, so you could return early and save a lot of time.

    Beyond that, there might be a better algorithm, but I can't think of it.

    Edit: Another idea.

    You can make 2 cases, depending on whether the first character matches. If it doesn't match, the rest of the word has to match exactly, and you can test for that in one shot. Otherwise, do it similarly to what you were doing. You could even do it recursively, but I don't think that would be faster.

    def DifferentByOne(word1, word2):
        if word1[0] != word2[0]:
            return word1[1:] == word2[1:]
        same = True
        for i in range(1, len(word1)):
            if word1[i] != word2[i]:
                if same:
                    same = False
                else:
                    return False
        return not same
    

    Edit 2: I've deleted the check to see if the strings are the same length, since you say it's redundant. Running Ryan's tests on my own code and on the is_neighbors function provided by MizardX, I get the following:

    • Original distance(): 3.7 seconds
    • My DifferentByOne(): 1.1 seconds
    • MizardX's is_neighbors(): 3.7 seconds

    Edit 3: (Probably getting into community wiki territory here, but...)

    Trying your final definition of is_neighbors() with izip instead of zip: 2.9 seconds.

    Here's my latest version, which still times at 1.1 seconds:

    def DifferentByOne(word1, word2):
        if word1[0] != word2[0]:
            return word1[1:] == word2[1:]
        different = False
        for i in range(1, len(word1)):
            if word1[i] != word2[i]:
                if different:
                    return False
                different = True
        return different
    

提交回复
热议问题