我必须编写一个函数,它接受一个包含str形式的文本块的参数文本,并返回一个“对称”单词的排序列表。对称字被定义为一个单词,其中对于所有值i,字母i从单词的开头起定位,而字母i从单词的末尾起的位置与字母表的各个末端等距。例如,bevy是一个对称词,因为:b(从单词的开头开始的1个位置)是字母表的第二个字母,y(从单词的结尾开始的1个位置)是字母表的倒数第二个字母;和e(从单词的开头起2个位置)是字母表的第五个字母,v(单词末尾的2个位置)是字母表中倒数第5个字母。
例如:
>>> 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的位置,因为我不知道如何把它。有没有人可以帮助我?
答案 0 :(得分:3)
这是一个提示:
In [16]: alpha1.index('b')
Out[16]: 1
In [17]: alpha2.index('y')
Out[17]: 1
解决问题的另一种方法是使用str.translate()
方法:
import string
def is_sym(word):
alpha1 = 'abcdefghijklmnopqrstuvwxyz'
alpha2 = 'zyxwvutsrqponmlkjihgfedcba'
tr = string.maketrans(alpha1, alpha2)
n = len(word) // 2
return word[:n] == word[::-1][:n].translate(tr)
print(is_sym('aloz'))
print(is_sym('boy'))
print(is_sym('bread'))
(翻译表的构建可以很容易地计算出来。)
答案 1 :(得分: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
答案 2 :(得分:0)
根据您的对称规则,我们可以使用以下is_symmetric_word
函数验证对称字:
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']
答案 3 :(得分:0)
代码优先。在代码下面讨论。
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有你可以使用的副本时输入字母?所以我也做了那个改变。 编辑:@heltonbiker的更改引入了对Python版本的依赖!我使用合适的try:
/ except
块将其留下来处理问题。似乎Python 3.x已将小写ASCII字母的名称改为string.ascii_lowercase
而不是普通string.lowercase
。