的Python如何通过一个对一个单词列表里的词匹配的句子中某些符号标记的字符串来跳过部分
我试图重建一个句子:的Python如何通过一个对一个单词列表里的词匹配的句子中某些符号标记的字符串来跳过部分
text='acatisananimal'
words=['cat','is','an','a','animal']
for i in words:
if i in text:
final=text.replace(i,' '+i)
text=final
print(final)
的?预计产量会像:
a cat is an animal
如果我跑我的代码中,“一”和“一个”在“动物”将不可避免地分开了。 所以我想根据长度对单词列表进行排序,并首先搜索长单词。
words.sort(key=len)
words=words[::-1]
然后我想用特殊符号标记长单词,并期望程序可以跳过我标记的部分。例如:
acatisan%animal&
最后我会擦除符号。但我卡在这里。我不知道该怎么做才能让程序跳过'%'和'&'之间的某些部分。谁能帮我??或者有更好的方法来解决间距问题吗?非常感谢!
**对于另一种情况,如果文本包括不包括在单词列表中的单词?我怎么会处理此事?
text=‘wowwwwacatisananimal’
也许你可以用食指替换词,所以在final
字符串应该是这样的3 0 1 2 4
,然后将其转换回一句:
text='acatisananimal'
words=['cat','is','an','a','animal']
for i in sorted(words,key=len,reverse=True):
if i in text:
final=text.replace(i,' %s'%words.index(i))
text=final
print(" ".join(words[int(i)] for i in final.split()))
输出:
a cat is an animal
你需要一个小的修改在你的代码,更新代码行
final=text.replace(i,' '+i)
to
final=text.replace(i,' '+i, 1)
。这将只取代第一次出现。
所以更新的代码将
text='acatisananimal'
words=['cat','is','an','a','animal']
for i in words:
if i in text:
final=text.replace(i,' '+i, 1)
text=final
print(final)
输出是:
a cat is an animal
如果您在仅去除符号的一部分得到......那么正则表达式是你的,你在找什么for..import一个名为re的模块并执行此操作。
import re
code here
print re.sub(r'\W+', ' ', final)
一个更广义的办法是找一开始所有有效的话,分裂他们的时间,探索信件的其余部分,例如:
def compose(letters, words):
q = [(letters, [])]
while q:
letters, result = q.pop()
if not letters:
return ' '.join(result)
for word in words:
if letters.startswith(word):
q.append((letters[len(word):], result+[word]))
>>> words=['cat','is','an','a','animal']
>>> compose('acatisananimal', words)
'a cat is an animal'
如果有潜在的多个可能的话将它变成微不足道的组合来将其变成发生器并用yield
代替return
以产生所有匹配的句子组成。
人为的例子(只是return
与yield
替换):
>>> words=['adult', 'sex', 'adults', 'exchange', 'change']
>>> list(compose('adultsexchange', words))
['adults exchange', 'adult sex change']
我不会建议使用您匹配的单词不同的定界符两边
它更容易(%
并在你的例子&
。)在标记的单词的任一侧使用相同的分隔符并使用Python的列表分片。
以下解决方案使用[::n]
语法获取列表中的每个n
个元素。
a[::2]
得到偶数编号的元素,a[1::2]
得到奇数。
>>> fox = "the|quick|brown|fox|jumpsoverthelazydog"
因为他们两边|
字符,'quick'
和'fox'
是奇数的元素,当你劈在|
字符串:
>>> splitfox = fox.split('|')
>>> splitfox
['the', 'quick', 'brown', 'fox', 'jumpsoverthelazydog']
>>> splitfox[1::2]
['quick', 'fox']
,其余均为偶数:
>>> splitfox[::2]
['the', 'brown', 'jumpsoverthelazydog']
因此,通过将|
字符中的已知单词括起来,分割并扫描even-nu复杂的元素,您只能搜索那些尚未匹配的文本部分。这意味着你在已经匹配的单词中不匹配。
from itertools import chain
def flatten(list_of_lists):
return chain.from_iterable(list_of_lists)
def parse(source_text, words):
words.sort(key=len, reverse=True)
texts = [source_text, ''] # even number of elements helps zip function
for word in words:
new_matches_and_text = []
for text in texts[::2]:
new_matches_and_text.append(text.replace(word, f"|{word}|"))
previously_matched = texts[1::2]
# merge new matches back in
merged = '|'.join(flatten(zip(new_matches_and_text, previously_matched)))
texts = merged.split('|')
# remove blank words (matches at start or end of a string)
texts = [text for text in texts if text]
return ' '.join(texts)
>>> parse('acatisananimal', ['cat', 'is', 'a', 'an', 'animal'])
'a cat is an animal'
>>> parse('atigerisanenormousscaryandbeautifulanimal', ['tiger', 'is', 'an', 'and', 'animal'])
'a tiger is an enormousscary and beautiful animal'
的merge
代码使用zip
和flatten
功能拼接的新比赛和老一起匹配。它基本上是通过将列表中的偶数和奇数元素进行配对来实现的,然后将结果“拼合”成一个长列表,为下一个单词做好准备。
该方法在文本中留下无法识别的单词。
'beautiful'
和'a'
处理得好,因为他们对自己的(即靠近识别的单词。)
'enormous'
和'scary'
不是已知的,因为他们是彼此相邻,他们离开粘在一起。
下面是如何列出未知的话:
>>> known_words = ['cat', 'is', 'an', 'animal']
>>> sentence = parse('anayeayeisananimal', known_words)
>>> [word for word in sentence.split(' ') if word not in known_words]
['ayeaye']
我很好奇:这是一个生物信息学项目?
列表和字典的理解是另一种方式来做到这一点:
result = ' '.join([word for word, _ in sorted([(k, v) for k, v in zip(words, [text.find(word) for word in words])], key=lambda x: x[1])])
所以,我用zip
单词及其在文本位置,sorted
的话通过他们的位置在原始文本结合,最后加入结果与' '
。
'Simple is (来自https://www.python.org/dev/peps/pep-0020/) – boardrider
@boardrider理解是一种解决循环的非常快速和pythonic的方式。你有建议让它更好? – zipa
虽然确实,列表理解速度很快,性能在这里似乎不是一个问题,@ zipa - 正如我在Python的_Zen引用中指出的那样,_优选(和Pythonic)使用*简单理解*语法,而不是你提出的几乎难以理解的长期理解。 – boardrider
你现在的输出是什么? –
@ t.m.adam嗯,我知道。但是,当我在评论的上下文中使用定义时,我问的是“最终”初始化_任何地方_。但是,是的,你完全正确。 –
[我的解决方案](http://stackoverflow.com/a/43366440/5811078)也适用于这种情况。 – zipa