2016-09-07 2 views
4

나는 문장이, 이제 가정 해 봅시다 :어떻게 파이썬에서 문장의 일부를 뒤집을 수 있습니까?

빠른 갈색 여우가 게으른 개를 내가 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

인수 (목록)에는 무시해야하는 문장의 부분이 있습니다. 단 한 마디가 아닙니다.

정규 표현식을 사용해야합니까?

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

반환 : 그냥 처음에 당신이 올바른 방법으로 주위에 원하는 문구를 반대하지 왜 ... 그것을 피하기 위해 대신 자리의

+0

당신이 단어 또는 전체 문구를 무시하고 있습니까? –

+0

나는 전체 구절을 무시하려고합니다. – Bravi

+0

갈색이 나중에 나타나면 빠르게 뒤집어지지 않아야합니다. –

답변

0

을 시도하고 있었다, 다음, 전체 문자열을 역

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

'[게으른 개 ','빠른 갈색 ']'이 있다면? – furas

+0

이것은 나쁜 생각은 아니지만 변경되지 않은 상태로 유지되는 구문의 '목록'이 반복 횟수 (문장의 모든 인스턴스를 무시할 수는 없으며 한 번에 하나씩 만 무시할 수 있음)와 문장 구조와 일치해야합니다. order ('ignores '는 문장에서 보이는 순서와 정확하게 일치해야 함). – ShadowRanger

+0

나는 각 문장이 문장에서 발견 된 색인을 먼저 찾은 다음 그 색인에 의해 정렬을 무시한 다음 치환을 수행 할 수 있다고 생각합니다. – SuperShoot

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

'설정'대신'왜 '를 사용합니까? –

+0

@StefanPochmann : 나중에 수정하지 않을 이유는 절대적으로 없습니다. 실제로 파이썬의 현재 버전은'frozenset'을위한 특별한 최적화를 수행하지 않으며'set'과'frozenset'의 내부 구조는 동일하므로 변경하지 않으면 유일한 차이점이 있습니다. 'dict' 키나'set' 멤버로서 사용하기에 적합하다). 그러나 나는 돌연변이가 의도되지 않을 때'frozenset'을 사용한다; 그렇게하는 데 비용이 들지 않으며 필요한 경우 언제든지 변경할 수 있습니다. 구문이 서로의 하위 구문 일 수 있다면'collections.OrderedDict'가 주문을 보존하기를 원할 것입니다. – ShadowRanger

+0

이것은 매우 깨끗하고 읽기 쉽고, 나는 정규식을 사용하는 것을 피하려고 노력했다. – Bravi

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

당신이 그것을 덜 읽을 수 있다고 생각하지 않는다;) –

+1

@PadraicCunningham 당신은 나를 과소 평가한다. 예를 들어'r'과 모든 변수의 이름을'_'로 바꾸는 것은 어떻습니까? 즉, 'def _ (_) : return' '.join (_ [_ - :: _]에서 _에 대한)'? –

0

내가 무시 중복 문구, 예를 들어 문제를 해결하기 위해 시도 ['brown fox', 'quick brown'] @PadraicCunningham 님이 올린 성기.

루핑이 훨씬 더 많고 코드가 덜 파이썬 적이기 때문에 개선 방법에 대한 의견을 듣고 싶습니다.

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 
관련 문제