Temukan frase kata benda sebelum dan sesudah angka dalam teks

Aug 19 2020

Diberikan teks saya harus menemukan kata-kata sebelumnya untuk semua angka hingga kata berhenti milik daftar check_words (jenis stopwords).

Kode saya:

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

Dalam teks tertentu saya akan memeriksa sebelumnya '78'dan '45'dan akan kembali ke titik di mana saya menemukan kata-kata dalam check_words (tetapi tidak lebih dari 8 kata).

Kode untuk melakukan itu mungkin:

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

Kode ini berfungsi. pada dasarnya saya memeriksa setiap kata tapi saya mendapat kesan (mungkin saya salah) bahwa itu dapat dicapai dengan beberapa kalimat dan karenanya tanpa loop. Ada ide?


CATATAN: Pertanyaan ini tentang meningkatkan keterbacaan kode, mencoba menghilangkan loop untuk membuat kode lebih cepat, dan mencoba membuat kode lebih bagus, yang merupakan bagian dari Zen of Python.


CATATAN 2: Beberapa pemeriksaan sebelumnya yang saya lakukan:

  • Menemukan posisi item dalam daftar lain dari nomor dalam daftar berbeda
  • Menemukan indeks item dalam daftar
  • Temukan dalam daftar

Jawaban

MarioIshac Aug 19 2020 at 09:13

Saya datang dengan ini:

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)

Kami menerapkan itertools.takewhileke reversed_chunkyang memberi kita potongan sebelumnya dalam urutan terbalik. Kami kemudian mendapatkan urutan yang benar preceding_chunkdengan membalik di akhir dengan [::-1].

Regex dipisahkan mystringberdasarkan angka (yang di-escape \d+). Escaped di sekitarnya \s+mewakili padding di sekitar nomor tersebut. Ini menyebabkan kode ini memiliki perilaku yang berbeda dari Anda jika angka dan huruf dicampur dalam kata yang sama (misalnya, a1).

Untuk kode asli Anda, saya akan membuat beberapa saran:

  1. Ikuti PEP 8 . Misalnya, tambahkan spasi setelah koma in i,word.
  2. Hapus ekspresi yang berlebihan preceding_words[::-1]. Meskipun ini mengevaluasi kebalikannya preceding_words, karena tidak pada tempatnya, evaluasi tidak memiliki efek samping. Plus, Anda sudah melakukan pembalikan ini di enumerate(preceding_words[::-1]).