在字符串中查找单词的 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')]
我正在尝试输入一个字符串,例如一个句子,并找出句子中所有具有反向词的单词。到目前为止我有这个:
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')]