How can I cancel parts of a sentence in python?

I have a suggestion, say:

Fast brown fox jumps over a lazy dog

I want to create a function that takes 2 arguments, a sentence and a list of things to ignore. And he returns this sentence with the opposite words, however, he should ignore the material that I pass to him in the second argument. This is what I have at the moment:

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

But this will only work if I pass the second list:

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

However, I want to pass the list as follows:

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

Expected Result: ehT quick brown xof spmuj revo eht lazy dog

Thus, basically the second argument (list) will contain parts of the sentence that should be ignored. Not just single words.

Should I use regexp for this? I tried to avoid this ...

+4
4

, - , -, :

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
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)
0

Another idea, the opposite of every word, and then the reverse ignoring on the right:

>>> 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'
0
source

I tried to solve the problem of overlapping ignoring phrases, for example. ['brown fox', 'quick brown']taken up by @PadraicCunningham.

Obviously there are a lot more loops, and the code feels less pythonic, so I would be interested to get feedback on how to improve this.

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']))

results:

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
0
source

Source: https://habr.com/ru/post/1653849/


All Articles