如何在python中反转部分句子?

时间:2016-09-07 00:21:29

标签: python python-3.x

我有一句话,让我们说:

快速的棕色狐狸跳过懒狗

我想创建一个带有2个参数的函数,一个句子和一个要忽略的事物列表。并且它返回带有反转词的句子,但它应该忽略我在第二个参数中传递给它的东西。这就是我现在所拥有的:

def main(sentence, ignores):
    return ' '.join(word[::-1] if word not in ignores else word for word in sentence.split())

但是这只有在我传递第二个列表时才会起作用:

print(main('The quick brown fox jumps over the lazy dog', ['quick', 'lazy']))

但是,我想传递一个这样的列表:

print(main('The quick brown fox jumps over the lazy dog', ['quick brown', 'lazy dog']))

预期结果: ehT quick brown xof spmuj revo eht lazy dog

所以基本上第二个参数(列表)将包含应忽略的句子部分。不只是单个单词。

我必须使用正则表达式吗?我试图避免它...

4 个答案:

答案 0 :(得分:0)

而不是占位符,为什么不最初反转任何你想要的正确方式的短语,然后反转整个字符串:

def main(sentence, ignores):
    for phrase in ignores:
        reversed_phrase = ' '.join([word[::-1] for word in phrase.split()])
        sentence = sentence.replace(phrase, reversed_phrase)

    return ' '.join(word[::-1] for word in sentence.split())

print(main('The quick brown fox jumps over the lazy dog', ['quick', 'lazy']))
print(main('The quick brown fox jumps over the lazy dog', ['quick brown', 'lazy dog']))

返回:

ehT quick nworb xof spmuj revo eht lazy god
ehT quick brown xof spmuj revo eht lazy dog

答案 1 :(得分:0)

我是第一个建议避免使用正则表达式的人,但在这种情况下,不使用它的复杂性大于使用它们所增加的复杂性:

import re

def main(sentence, ignores):
    # Dedup and allow fast lookup for determining whether to reverse a component
    ignores = frozenset(ignores)

    # Make a pattern that will prefer matching the ignore phrases, but
    # otherwise matches each space and non-space run (so nothing is dropped)
    # Alternations match the first pattern by preference, so you'll match
    # the ignores phrases if possible, and general space/non-space patterns
    # otherwise
    pat = r'|'.join(map(re.escape, ignores)) + r'|\S+|\s+'

    # Returns the chopped up pieces (space and non-space runs, but ignore phrases stay together
    parts = re.findall(pat, sentence)

    # Reverse everything not found in ignores and then put it all back together
    return ''.join(p if p in ignores else p[::-1] for p in parts)

答案 2 :(得分:0)

只是另一个想法,反转每个单词然后反转忽略右后方:

>>> from functools import reduce
>>> def main(sentence, ignores):
        def r(s):
            return ' '.join(w[::-1] for w in s.split())
        return reduce(lambda s, i: s.replace(r(i), i), ignores, r(sentence))

>>> main('The quick brown fox jumps over the lazy dog', ['quick brown', 'lazy dog'])
'ehT quick brown xof spmuj revo eht lazy dog'

答案 3 :(得分:0)

我试图解决重叠忽略短语的问题,例如['brown fox', 'quick brown']由@PadraicCunningham提出。

显然循环更多,代码感觉更少pythonic所以我对如何改进这一点的反馈很感兴趣。

import re

def _span_combiner(spans):
    """replace overlapping spans with encompasing single span"""
    for i, s in enumerate(spans):
        start = s[0]
        end = s[1]
        for x in spans[i:]:
            if x[0] < end:
                end = x[1]
        yield (start, end) 

def main(sentence, ignores):
    # spans is a start and finish indices for each ignore phrase in order of occurence
    spans = sorted(
            [[m.span() for m in re.finditer(p, sentence)][0] for p in ignores if p in sentence]
    )
    # replace overlapping indices with single set of indices encompasing overlapped range
    spans = [s for s in _span_combiner(spans)]
    # recreate ignore list by slicing sentence with combined spans
    ignores = [sentence[s[0]:s[1]] for s in spans]
    for phrase in ignores:
        reversed_phrase = ' '.join([word[::-1] for word in phrase.split()])
        sentence = sentence.replace(phrase, reversed_phrase)

    return ' '.join(word[::-1] for word in sentence.split())

if __name__ == "__main__":
    print(main('The quick brown fox jumps over the lazy dog', ['quick', 'lazy']))
    print(main('The quick brown fox jumps over the lazy dog', ['brown fox', 'lazy dog']))
    print(main('The quick brown fox jumps over the lazy dog', ['nonexistent' ,'brown fox', 'quick brown']))
    print(main('The quick brown fox jumps over the brown fox', ['brown fox', 'quick brown']))

结果:

ehT quick nworb xof spmuj revo eht lazy god
ehT kciuq brown fox spmuj revo eht lazy dog
ehT quick brown fox spmuj revo eht yzal god
ehT quick brown fox spmuj revo eht brown fox