Python 在文本中查找对称词
我必须编写一个函数,它接受一个参数文本,该文本包含str形式的文本块,并返回“对称”字的排序列表。对称字定义为一个字,其中对于所有值i,从字的开头开始的字母i位置和从字的结尾开始的字母i位置与字母表各自的末端等距。例如,bevy是一个对称的单词,因为:b(从单词开始的1个位置)是字母表的第二个字母,y(从单词结束的1个位置)是字母表的第二个最后一个字母;e(从单词开始的两个位置)是字母表的第五个字母,v(从单词结束的两个位置)是字母表的最后五个字母 例如:Python 在文本中查找对称词,python,function,Python,Function,我必须编写一个函数,它接受一个参数文本,该文本包含str形式的文本块,并返回“对称”字的排序列表。对称字定义为一个字,其中对于所有值i,从字的开头开始的字母i位置和从字的结尾开始的字母i位置与字母表各自的末端等距。例如,bevy是一个对称的单词,因为:b(从单词开始的1个位置)是字母表的第二个字母,y(从单词结束的1个位置)是字母表的第二个最后一个字母;e(从单词开始的两个位置)是字母表的第五个字母,v(从单词结束的两个位置)是字母表的最后五个字母 例如: >>> symmet
>>> symmetrics("boy bread aloz bray")
['aloz','boy']
>>> symmetrics("There is a car and a book;")
['a']
我所能想到的解决方案是这样的,但我无法运行它,因为它是错误的:
def symmetrics(text):
func_char= ",.?!:'\/"
for letter in text:
if letter in func_char:
text = text.replace(letter, ' ')
alpha1 = 'abcdefghijklmnopqrstuvwxyz'
alpha2 = 'zyxwvutsrqponmlkjihgfedcba'
sym = []
for word in text.lower().split():
n = range(0,len(word))
if word[n] == word[len(word)-1-n]:
sym.append(word)
return sym
上面的代码没有考虑alpha1和alpha2的位置,因为我不知道如何使用它。有人能帮我吗?这里有个提示:
In [16]: alpha1.index('b')
Out[16]: 1
In [17]: alpha2.index('y')
Out[17]: 1
解决问题的另一种方法是使用以下方法:
(翻译表的构建很容易考虑。)这里有一个提示:
In [16]: alpha1.index('b')
Out[16]: 1
In [17]: alpha2.index('y')
Out[17]: 1
解决问题的另一种方法是使用以下方法:
(转换表的构建可以很容易地分解出来。)for循环可以修改为:
for word in text.lower().split():
for n in range(0,len(word)//2):
if alpha1.index(word[n]) != alpha2.index(word[len(word)-1-n]):
break
else:
sym.append(word)
return sym
for循环可以修改为:
for word in text.lower().split():
for n in range(0,len(word)//2):
if alpha1.index(word[n]) != alpha2.index(word[len(word)-1-n]):
break
else:
sym.append(word)
return sym
根据您的对称规则,我们可以使用以下功能验证对称字:
def is_symmetric_word(word):
alpha1 = 'abcdefghijklmnopqrstuvwxyz'
alpha2 = 'zyxwvutsrqponmlkjihgfedcba'
length = len(word)
for i in range(length / 2):
if alpha1.index(word[i]) != alpha2.index(word[length - 1 - i]):
return False
return True
然后,从文本中获取所有唯一对称单词的整个函数可以定义为:
def is_symmetrics(text):
func_char= ",.?!:'\/;"
for letter in text:
if letter in func_char:
text = text.replace(letter, ' ')
sym = []
for word in text.lower().split():
if is_symmetric_word(word) and not (word in sym):
sym.append(word)
return sym
以下是您提供的两个测试用例:
is_symmetrics("boy bread aloz bray") #['boy', 'aloz']
is_symmetrics("There is a car and a book;") #['a']
根据您的对称规则,我们可以使用以下功能验证对称字:
def is_symmetric_word(word):
alpha1 = 'abcdefghijklmnopqrstuvwxyz'
alpha2 = 'zyxwvutsrqponmlkjihgfedcba'
length = len(word)
for i in range(length / 2):
if alpha1.index(word[i]) != alpha2.index(word[length - 1 - i]):
return False
return True
然后,从文本中获取所有唯一对称单词的整个函数可以定义为:
def is_symmetrics(text):
func_char= ",.?!:'\/;"
for letter in text:
if letter in func_char:
text = text.replace(letter, ' ')
sym = []
for word in text.lower().split():
if is_symmetric_word(word) and not (word in sym):
sym.append(word)
return sym
以下是您提供的两个测试用例:
is_symmetrics("boy bread aloz bray") #['boy', 'aloz']
is_symmetrics("There is a car and a book;") #['a']
先编码。代码下面的讨论
import string
# get alphabet and reversed alphabet
try:
# Python 2.x
alpha1 = string.lowercase
except AttributeError:
# Python 3.x and newer
alpha1 = string.ascii_lowercase
alpha2 = alpha1[::-1] # use slicing to reverse alpha1
# make a dictionary where the key, value pairs are symmetric
# for example symd['a'] == 'z', symd['b'] == 'y', and so on
_symd = dict(zip(alpha1, alpha2))
def is_symmetric_word(word):
if not word:
return False # zero-length word is not symmetric
i1 = 0
i2 = len(word) - 1
while True:
if i1 >= i2:
return True # we have checked the whole string
# get a pair of chars
c1 = word[i1]
c2 = word[i2]
if _symd[c1] != c2:
return False # the pair wasn't symmetric
i1 += 1
i2 -= 1
# note, added a space to list of chars to filter to a space
_filter_to_space = ",.?!:'\/ "
def _filter_ch(ch):
if ch in _filter_to_space:
return ' ' # return a space
elif ch in alpha1:
return ch # it's an alphabet letter so return it
else:
# It's something we don't want. Return empty string.
return ''
def clean(text):
return ''.join(_filter_ch(ch) for ch in text.lower())
def symmetrics(text):
# filter text: keep only chars in the alphabet or spaces
for word in clean(text).split():
if is_symmetric_word(word):
# use of yield makes this a generator.
yield word
lst = list(symmetrics("The boy...is a yob."))
print(lst) # prints: ['boy', 'a', 'yob']
- 不需要输入两次字母表;我们可以把第一个倒过来
- 我们可以制作一本字典,将每个字母与其对称字母配对。这将使测试任何给定的字母对是否为对称对变得非常容易。函数
从两个序列进行配对;它们的长度必须相同,但由于我们使用的是字符串和字符串的反向副本,因此它们的长度将相同zip()
- 最好编写一个简单的函数,它只做一件事,所以我们编写一个函数,它只检查字符串是否对称。如果给它一个长度为零的字符串,它将返回
,否则它将False
设置为字符串中的第一个字符,i1
设置为最后一个字符。只要字符继续对称,它就会对字符进行比较,并递增i2
,同时递减i1
。如果这两个字符串相遇或通过,我们知道我们看到了整个字符串,它必须是对称的,在这种情况下,我们返回i2
;如果它发现任何一对不对称的字符,它将返回True
。我们必须检查False
和i1
是否在循环的顶部相遇或通过,这样它就不会尝试检查字符是否是自己的对称字符。(一个字符不能同时是i2
和'A'
,因此一个字符永远不是它自己的对称字符!)'z'
- 现在我们编写一个包装器,过滤掉垃圾,将字符串拆分成单词,并测试每个单词。它不仅将所选的标点符号转换为空格,还将删除任何意外字符(任何不是经批准的标点符号字符、空格或字母的字符)。这样我们就知道,没有什么意外的事情会通过内部功能。包装是“懒惰的”。。。它是一个一次生成一个单词的生成器,而不是构建整个列表并返回该列表。很容易使用
将生成器的结果强制放入列表中。如果需要,您可以轻松地修改此函数,只需构建一个列表并返回它list()
编辑:@heltonbiker的更改引入了对Python版本的依赖!我留下了一个合适的
try:
/块来处理这个问题。Python3.x似乎已经将小写ASCII字母表的名称改进为string.ASCII_lowercase
,而不是普通的string.lowercase
代码优先。代码下面的讨论
import string
# get alphabet and reversed alphabet
try:
# Python 2.x
alpha1 = string.lowercase
except AttributeError:
# Python 3.x and newer
alpha1 = string.ascii_lowercase
alpha2 = alpha1[::-1] # use slicing to reverse alpha1
# make a dictionary where the key, value pairs are symmetric
# for example symd['a'] == 'z', symd['b'] == 'y', and so on
_symd = dict(zip(alpha1, alpha2))
def is_symmetric_word(word):
if not word:
return False # zero-length word is not symmetric
i1 = 0
i2 = len(word) - 1
while True:
if i1 >= i2:
return True # we have checked the whole string
# get a pair of chars
c1 = word[i1]
c2 = word[i2]
if _symd[c1] != c2:
return False # the pair wasn't symmetric
i1 += 1
i2 -= 1
# note, added a space to list of chars to filter to a space
_filter_to_space = ",.?!:'\/ "
def _filter_ch(ch):
if ch in _filter_to_space:
return ' ' # return a space
elif ch in alpha1:
return ch # it's an alphabet letter so return it
else:
# It's something we don't want. Return empty string.
return ''
def clean(text):
return ''.join(_filter_ch(ch) for ch in text.lower())
def symmetrics(text):
# filter text: keep only chars in the alphabet or spaces
for word in clean(text).split():
if is_symmetric_word(word):
# use of yield makes this a generator.
yield word
lst = list(symmetrics("The boy...is a yob."))
print(lst) # prints: ['boy', 'a', 'yob']
- 不需要输入两次字母表;我们可以把第一个倒过来
- 我们可以制作一本字典,将每个字母与其对称字母配对。这将使测试任何给定的字母对是否为对称对变得非常容易。函数
zip()
从两个序列进行配对;它们的长度必须相同,但由于我们使用的是字符串和字符串的反向副本,因此它们的长度将相同
- 最好编写一个简单的函数,它只做一件事,所以我们编写一个函数,它只检查字符串是否对称。如果给它一个长度为零的字符串,它将返回
False
,否则它将i1
设置为字符串中的第一个字符,i2
设置为最后一个字符。只要字符继续对称,它就会对字符进行比较,并递增i1
,同时递减i2
。如果这两个字符串相遇或通过,我们知道我们看到了整个字符串,它必须是对称的,在这种情况下,我们返回