我有这个功能可以检查第一个序列中的所有单词, 如果它们以第二个序列中的一个单词结尾,则删除该结束子字符串。
我试图在一个简单的lambda函数中实现所有这一切,该函数应该进入流水线处理,并且无法找到一种方法。
如果你能帮助我,我将不胜感激:
str_test = ("Thiship is a test string testing slowly i'm helpless")
stem_rules = ('less', 'ship', 'ing', 'es', 'ly','s')
str_test2 = str_test.split()
for i in str_test2:
for j in stem_rules:
if(i.endswith(j)):
str_test2[str_test2.index(i)] = i[:-len(j)]
break
答案 0 :(得分:3)
这是一个激活(简单?)lambda的单线程。
(lambda words, rules: sum([[word[:-len(rule)]] if word.endswith(rule) else [] for word in words for rule in rules], []))(str_test.split(), stem_rules)
目前尚不清楚它是如何运作的,这样做并不好。
它通常做的是创建一个列表,其中包含一个匹配的字符串,或一个空缺列表,然后将所有内容聚合到单个列表中,仅包含匹配项。
目前它会在每次匹配时输出,而不仅仅是最长匹配或类似的东西,但是一旦你弄清楚它是如何工作的,也许你可以选择最短的匹配输入中每个单词的匹配列表。
愿上帝与你同在。答案 1 :(得分:1)
我要做的第一件事就是抛出你的i.endswith(j) for j in stem_rules
并使其成为匹配并捕获前缀字符串并匹配(但不会捕获)任何后缀的正则表达式
import re
match_end = re.compile("(.*?)(?:" + "|".join(".*?" + stem + "$" for stem in stem_rules) + ")")
# This is the same as:
re.compile(r"""
(.*?) # Capturing group matching the prefix
(?: # Begins a non-capturing group...
stem1$|
stem2$|
stem3$ # ...which matches an alternation of the stems, asserting end of string
) # ends the non-capturing group""", re.X)
然后,您可以使用该正则表达式对列表中的每个项目进行分项。
f = lambda word: match_end.sub(r"\1", word)
使用包含在列表推导中的内容,你应该得到你的结果
words = [f(word) for word in str_test.split()]
# or map(f, str_test.split())
答案 2 :(得分:0)
要将当前代码转换为单个lambda,管道中的每个步骤都需要以非常实用的方式运行:接收一些数据,然后发出一些数据。你需要避免任何偏离这种范式的东西 - 特别是使用像break
这样的东西。这是以这种方式重写步骤的一种方法:
text = ("Thiship is a test string testing slowly i'm helpless")
stems = ('less', 'ship', 'ing', 'es', 'ly','s')
# The steps:
# - get words from the text
# - pair each word with its matching stems
# - create a list of cleaned words (stems removed)
# - make the new text
words = text.split()
wstems = [ (w, [s for s in stems if w.endswith(s)]) for w in words ]
cwords = [ w[0:-len(ss[0])] if ss else w for w, ss in wstems ]
text2 = ' '.join(cwords)
print text2
掌握这些部件后,可以使用普通替换创建单个lambda。这是怪物:
f = lambda txt: [
w[0:-len(ss[0])] if ss else w
for w, ss in [ (w, [s for s in stems if w.endswith(s)]) for w in txt.split() ]
]
text3 = ' '.join(f(text))
print text3
我不确定您是否希望lambda返回新单词或新文本 - 根据需要进行调整。