2017-10-04 7 views
2

特定の単語が出現するたびに、単語の出現の前後に約5語を表示してコンテキストを表示する必要があります。コンテンツのテキストファイル内の単語「他人」のテキストファイルの各単語について、周囲の5ワードを抽出します。

出力例あなたはoccurs('stranger', 'movie.txt')を入力します。

私のコード今のところ:

def occurs(word, filename): 

    infile = open(filename,'r') 
    lines = infile.read().splitlines() 
    infile.close() 

    wordsString = ''.join(lines) 
    words = wordsString.split() 
    print(words) 

    for i in range(len(words)): 
     if words[i].find(word): 
      #stuck here 
+0

先行する単語を印刷します。現在の単語が位置「i」である場合、その単語の前の単語は「i- ...」の位置にあるか? – TessellatingHeckler

+0

与えられた入力の期待される結果を表示してください – pylang

答えて

4

私はiに応じてwordsをスライスすることをお勧めしたい:

print(words[i-5:i+6]) 

(これはあなたのコメントがどこになるか)

はまた、あなたの例のように印刷するには:

print("...", " ".join(words[i-5:i+6]), "...") 

を最初の5にある単語を説明するために:

if i > 5: 
    print("...", " ".join(words[i-5:i+6]), "...") 
else: 
    print("...", " ".join(words[0:i+6]), "...") 

さらに、findは、あなたがそれだと思う何をしていません。 find()が文字列を見つけられない場合は、-1を返します。これは、if文で使用するとTrueと評価されます。試してみてください。これは、ファイル内のすべての単語のリストであるwords内の単語のすべての出現のインデックスを検索して、

if word in words[i].lower(): 
+0

私はそれを試しましたが、これは出力とテキストファイルです:https://imgur.com/a/5qdmK。 – sam44

+1

私はこの問題を@ sam44 –

0

。その後、スライシングを使用して、一致した単語とその前後の5単語のリストを取得します。

def occurs(word, filename): 
    infile = open(filename,'r') 
    lines = infile.read().splitlines() 
    infile.close() 

    wordsString = ''.join(lines) 
    words = wordsString.split() 

    matches = [i for i, w in enumerate(words) if w.lower().find(word) != -1] 

    for m in matches: 
     l = " ".join(words[m-5:m+6]) 
     print(f"... {l} ...") 
+1

解決したと思うかもしれません。もし 'word in w.lower()'?句読点と大文字を説明する –

+0

@ElliotRoberts良い点。等価性をチェックするのではなく、 'find()'を使用していなければなりません。 – Mark

0

more_itertools.adajacentツールを検討してください。

import more_itertools as mit 


s = """\ 
But we did not answer him, for he was a stranger and we were not used to, strangers and were shy of them. 
We were simple folk, in our village, and when a stranger was a pleasant person we were soon friends. 
""" 

word, distance = "stranger", 5 
words = s.splitlines()[0].split() 

デモ

neighbors = list(mit.adjacent(lambda x: x == word, words, distance)) 

" ".join(word for bool_, word in neighbors if bool_) 
# 'him, for he was a stranger and we were not used' 

詳細

more_itertools.adjacent考える

タプルの繰り返し可能性を返します。 (bool、アイテム)のペア​​。述語を満たす文字列の単語の場合は、Trueブール値が返されます。例:

>>> neighbors 
[(False, 'But'), 
... 
(True, 'a'), 
(True, 'stranger'), 
(True, 'and'), 
... 
(False, 'to,')] 

近隣単語がターゲットワードからdistance示す結果から除外されています。

注:more_itertoolsはサードパーティ製のライブラリです。 pip install more_itertoolsによってインストールします。私が思うに、私は、ファイルのローリング景色を見るたび

0

、このアプローチは、意図的に最初の5つのワードでneedle名やファイルの最後の5つの単語を任意のエッジケースを処理しないことをcollections.deque

import collections 

def occurs(needle, fname): 
    with open(fname) as f: 
     lines = f.readlines() 

    words = iter(''.join(lines).split()) 

    view = collections.deque(maxlen=11) 
    # prime the deque 
    for _ in range(10): # leaves an 11-length deque with 10 elements 
     view.append(next(words, "")) 
    for w in words: 
     view.append(w) 
     if view[5] == needle: 
      yield list(view.copy()) 

注意。質問は、第3の単語のマッチングが第1〜第9の単語を与えるべきかどうか、または異なるものについて曖昧である。

関連する問題