텍스트에서 숫자 앞뒤의 명사구 찾기

Aug 19 2020

텍스트가 주어지면 check_words 목록 (불용어의 종류)에 속하는 불용어까지 모든 숫자에 대한 선행 단어를 찾아야합니다.

내 코드 :

check_words = ['the', 'a', 'with','to']
mystring = 'the code to find the beautiful words 78 that i have to nicely check 45 with the snippet'
list_of_words = mystring.split()

특정 텍스트에서 나는 전에 확인 것 '78'그리고 '45'내가 check_words (그러나 더 8 이상의 단어)에있는 단어 중 하나를 찾을 어디 지점 뒤쪽으로 올라갈 것입니다.

이를 수행하는 코드는 다음과 같습니다.

preceding_chunks = []
for i,word in enumerate(list_of_words):
    if any(char.isdigit() for char in word):
       
        # 8 precedent words (taking into account that I can not slice with 8 back at the beginning)
        preceding_words = list_of_words[max(0,i-8):i]
        preceding_words[::-1]

        # I check from the end of the list towards the start
        for j,sub_word in enumerate(preceding_words[::-1]):
            if  sub_word in check_words:
                # printing out j for checking
                myposition = j
                print(j)
                real_preceding_chunk = preceding_words[len(preceding_words)-j:]
                print(real_preceding_chunk)
                preceding_chunks.append(real_preceding_chunk)
                break

이 코드는 작동합니다. 기본적으로 모든 단어를 확인합니다.하지만 한 두 개의 라이너를 사용하여 루프없이 달성 할 수 있다는 인상 (아마 제가 틀렸을 수도 있습니다)이 있습니다. 어떤 생각?


참고 :이 질문은 코드의 가독성을 높이고, 코드를 더 빠르게 만들기 위해 루프를 없애고, Zen of Python의 일부인 코드를 더 멋지게 만들려고합니다.


참고 2 : 내가 수행 한 몇 가지 이전 확인 :

  • 다른 목록의 번호에서 다른 목록의 항목 위치 찾기
  • 목록에서 항목의 색인 찾기
  • 목록에서 찾기

답변

MarioIshac Aug 19 2020 at 09:13

나는 이것을 생각 해냈다.

import itertools
import re

chunks = (grouped_chunk.split() for grouped_chunk in re.split("\\s+\\d+\\s+", mystring))
preceding_chunks = []

for reversed_chunk in map(reversed, chunks):
    preceding_chunk = list(itertools.takewhile(lambda word: word not in check_words, reversed_chunk))[::-1]
    preceding_chunks.append(preceding_chunk)

우리 는 이전 청크를 역순으로 제공하는에 적용 itertools.takewhile합니다 reversed_chunk. 그런 다음 preceding_chunk마지막에 [::-1].

정규식은 mystring숫자 (이스케이프 된 \d+)를 기준으로 분할 됩니다. 주변의 이스케이프 된 \s+s는 숫자 주변의 패딩을 나타냅니다. 이로 인해 숫자와 문자가 같은 단어 (예 :)에 혼합되어있는 경우이 코드가 사용자 코드와 다르게 동작 a1합니다.

원본 코드에 대해 몇 가지 제안을합니다.

  1. PEP 8을 따릅니다 . 예를 들어에서 쉼표 뒤에 공백을 추가 i,word합니다.
  2. 중복 식을 제거합니다 preceding_words[::-1]. 이것이 preceding_wordsin-place가 아니기 때문에 reversed로 평가되지만 평가에는 부작용이 없습니다. 또한에서 이미이 반전을 수행하고 enumerate(preceding_words[::-1])있습니다.