在字符串中查找单词的 semordnilap(反向字谜)

Find semordnilap(reverse anagram) of words in a string

我正在尝试输入一个字符串,例如一个句子,并找出句子中所有具有反向词的单词。到目前为止我有这个:

s = "Although he was stressed when he saw his desserts burnt, he managed to stop the pots from getting ruined"

def semordnilap(s):
    s = s.lower()
    b = "!@#$,"
    for char in b:
        s = s.replace(char,"")
    s = s.split(' ')

    dict = {}
    index=0
    for i in range(0,len(s)):
        originalfirst = s[index]
        sortedfirst = ''.join(sorted(str(s[index])))
        for j in range(index+1,len(s)):
            next = ''.join(sorted(str(s[j])))
            if sortedfirst == next:
                dict.update({originalfirst:s[j]})
        index+=1

    print (dict)

semordnilap(s)

所以这在大多数情况下都有效,但是如果你 运行 它,你会看到它也将 "he" 和 "he" 作为字谜配对,但这不是我想要的我在找。关于如何修复它的任何建议,以及是否有可能使 运行 时间更快,如果我要输入一个大文本文件。

您可以将字符串拆分成一个单词列表,然后比较所有组合的小写版本,其中一个组合是相反的。以下示例使用 re.findall() 将字符串拆分为单词列表并使用 itertools.combinations() 比较它们:

import itertools
import re

s = "Although he was stressed when he saw his desserts burnt, he managed to stop the pots from getting ruined"

words = re.findall(r'\w+', s)
pairs = [(a, b) for a, b in itertools.combinations(words, 2) if a.lower() == b.lower()[::-1]]

print(pairs)
# OUTPUT
# [('was', 'saw'), ('stressed', 'desserts'), ('stop', 'pots')]

编辑:我仍然更喜欢上面的解决方案,但是根据您关于在不导入任何包的情况下执行此操作的评论,请参见下文。但是,请注意,以这种方式使用 str.translate() 可能会产生意想不到的后果,具体取决于文本的性质(例如从电子邮件地址中删除 @)——换句话说,您可能需要比处理标点符号更仔细这个。此外,我通常会 import string 并使用 string.punctuation 而不是我传递给 str.translate() 的标点字符的文字字符串,但为了满足您在不导入的情况下执行此操作的请求,请避免在下面使用。

s = "Although he was stressed when he saw his desserts burnt, he managed to stop the pots from getting ruined"

words = s.translate(None, '!"#$%&\'()*+,-./:;<=>?@[\]^_`{|}~').split()
length = len(words)
pairs = []
for i in range(length - 1):
    for j in range(i + 1, length):
        if words[i].lower() == words[j].lower()[::-1]:
            pairs.append((words[i], words[j]))

print(pairs)
# OUTPUT
# [('was', 'saw'), ('stressed', 'desserts'), ('stop', 'pots')]