import string
from itertools import product, chain
from string import ascii_lowercase
from timeit import timeit
def _calc_edits1(word):
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in splits if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b) > 1]
replaces = [a + c + b[1:] for a, b in splits for c in
string.ascii_lowercase if b]
inserts = [a + c + b for a, b in splits for c in
string.ascii_lowercase]
return set(deletes + transposes + replaces + inserts)
def _split_word(word):
return ((word[:i], word[i:]) for i in range(len(word) + 1))
def _calc_edits2(word):
form_2, form_3, form_4 = "{}{}".format, "{}{}{}".format, "{}{}{}{}".format
deletes = (form_2(a, b[1:]) for a, b in _split_word(word) if b)
transposes = (form_4(a, b[1], b[0], b[2:])
for a, b in _split_word(word) if len(b) > 1)
replaces = (form_3(a, c, b[1:]) for a, b in _split_word(word) if b for c in
ascii_lowercase)
inserts = (form_3(a, c, b)
for (a, b), c in product(_split_word(word), ascii_lowercase))
return set(chain(deletes, transposes, replaces, inserts))
print(timeit("_calc_edits1('Welcome')",
"from __main__ import _calc_edits1", number=10000))
print(timeit("_calc_edits2('Welcome')",
"from __main__ import _calc_edits2", number=10000))
aW1wb3J0IHN0cmluZwpmcm9tIGl0ZXJ0b29scyBpbXBvcnQgcHJvZHVjdCwgY2hhaW4KZnJvbSBzdHJpbmcgaW1wb3J0IGFzY2lpX2xvd2VyY2FzZQpmcm9tIHRpbWVpdCBpbXBvcnQgdGltZWl0CgoKZGVmIF9jYWxjX2VkaXRzMSh3b3JkKToKICAgIHNwbGl0cyA9IFsod29yZFs6aV0sIHdvcmRbaTpdKSBmb3IgaSBpbiByYW5nZShsZW4od29yZCkgKyAxKV0KICAgIGRlbGV0ZXMgPSBbYSArIGJbMTpdIGZvciBhLCBiIGluIHNwbGl0cyBpZiBiXQogICAgdHJhbnNwb3NlcyA9IFthICsgYlsxXSArIGJbMF0gKyBiWzI6XSBmb3IgYSwgYiBpbiBzcGxpdHMgaWYgbGVuKGIpID4gMV0KICAgIHJlcGxhY2VzID0gW2EgKyBjICsgYlsxOl0gZm9yIGEsIGIgaW4gc3BsaXRzIGZvciBjIGluCiAgICAgICAgICAgICAgICBzdHJpbmcuYXNjaWlfbG93ZXJjYXNlIGlmIGJdCiAgICBpbnNlcnRzID0gW2EgKyBjICsgYiBmb3IgYSwgYiBpbiBzcGxpdHMgZm9yIGMgaW4KICAgICAgICAgICAgICAgc3RyaW5nLmFzY2lpX2xvd2VyY2FzZV0KICAgIHJldHVybiBzZXQoZGVsZXRlcyArIHRyYW5zcG9zZXMgKyByZXBsYWNlcyArIGluc2VydHMpCgoKZGVmIF9zcGxpdF93b3JkKHdvcmQpOgogICAgcmV0dXJuICgod29yZFs6aV0sIHdvcmRbaTpdKSBmb3IgaSBpbiByYW5nZShsZW4od29yZCkgKyAxKSkKCgpkZWYgX2NhbGNfZWRpdHMyKHdvcmQpOgogICAgZm9ybV8yLCBmb3JtXzMsIGZvcm1fNCA9ICJ7fXt9Ii5mb3JtYXQsICJ7fXt9e30iLmZvcm1hdCwgInt9e317fXt9Ii5mb3JtYXQKCiAgICBkZWxldGVzID0gKGZvcm1fMihhLCBiWzE6XSkgZm9yIGEsIGIgaW4gX3NwbGl0X3dvcmQod29yZCkgaWYgYikKICAgIHRyYW5zcG9zZXMgPSAoZm9ybV80KGEsIGJbMV0sIGJbMF0sIGJbMjpdKQogICAgICAgICAgICAgICAgICBmb3IgYSwgYiBpbiBfc3BsaXRfd29yZCh3b3JkKSBpZiBsZW4oYikgPiAxKQogICAgcmVwbGFjZXMgPSAoZm9ybV8zKGEsIGMsIGJbMTpdKSBmb3IgYSwgYiBpbiBfc3BsaXRfd29yZCh3b3JkKSBpZiBiIGZvciBjIGluCiAgICAgICAgICAgICAgICBhc2NpaV9sb3dlcmNhc2UpCiAgICBpbnNlcnRzID0gKGZvcm1fMyhhLCBjLCBiKQogICAgICAgICAgICAgICBmb3IgKGEsIGIpLCBjIGluIHByb2R1Y3QoX3NwbGl0X3dvcmQod29yZCksIGFzY2lpX2xvd2VyY2FzZSkpCgogICAgcmV0dXJuIHNldChjaGFpbihkZWxldGVzLCB0cmFuc3Bvc2VzLCByZXBsYWNlcywgaW5zZXJ0cykpCgoKcHJpbnQodGltZWl0KCJfY2FsY19lZGl0czEoJ1dlbGNvbWUnKSIsCiAgICAgICAgICAgICAiZnJvbSBfX21haW5fXyBpbXBvcnQgX2NhbGNfZWRpdHMxIiwgbnVtYmVyPTEwMDAwKSkKCnByaW50KHRpbWVpdCgiX2NhbGNfZWRpdHMyKCdXZWxjb21lJykiLAogICAgICAgICAgICAgImZyb20gX19tYWluX18gaW1wb3J0IF9jYWxjX2VkaXRzMiIsIG51bWJlcj0xMDAwMCkpCg==