2014-11-18 4 views
0

Я пытаюсь взять текстовый файл и взять все слова дольше трех букв и напечатать их в столбце. Затем я хочу сопоставить их с номерами строк, которые они отображаются во втором столбце. напримерПроверьте значения словаря для повторения чисел

Chicken 8,7 
Beef 9,4,1 
.... 

Проблема в том, что я не хочу иметь дубликаты. Прямо сейчас у меня есть слово «короли», которое появляется в строке дважды, и я только хочу, чтобы он печатался один раз. Я полностью тупик и нуждаюсь в помощи мудрого человека.

Мой код:

storyFile=open('StoryTime.txt', 'r') 

def indexMaker(inputFile): 
    '' 
    # Will scan in each word at a time and either place in index as a key or 
    # add to value. 
    index = {} 
    lineImOn = 0 
    for line in inputFile: 
     individualWord = line[:-1].split(' ') 
     lineImOn+=1 
     placeInList=0 
     for word in individualWord: 
      index.get(individualWord[placeInList]) 
      if(len(word) > 3): #Makes sure all words are longer then 3 letters 
       if(not individualWord[placeInList] in index): 
        index[individualWord[placeInList]] = [lineImOn] 

       elif(not index.get(individualWord[placeInList]) == str(lineImOn)): 
        type(index.get(individualWord[placeInList])) 
        index[individualWord[placeInList]].append(lineImOn) 
      placeInList+=1 

    return(index) 

print(indexMaker(storyFile)) 

Кроме того, если кто-нибудь знает что-нибудь о том, чтобы столбцы, которые вы бы огромную помощь и мой новый лучший друг.

ответ

0

Я хотел бы сделать это с помощью словаря наборов для отслеживания номеров строк. На самом деле для упрощения вещей я использовал бы collections.defaultdict со значениями, которые были типа set. Как уже упоминалось в другом ответе, лучше всего проанализировать слова, используя регулярное выражение через модуль re.

from collections import defaultdict 
import re 

# Only process words at least a minimum number of letters long. 
MIN_WORD_LEN = 3 
WORD_RE = re.compile('[a-zA-Z]{%s,}' % MIN_WORD_LEN) 

def make_index(input_file): 
    index = defaultdict(set) 

    for line_num, line in enumerate(input_file, start=1): 
     for word in re.findall(WORD_RE, line.lower()): 
      index[word].add(line_num) # Make sure line number is in word's set. 

    # Convert result into a regular dictionary of simple sequence values. 
    return {word:tuple(line_nums) for word, line_nums in index.iteritems()} 

Альтернативные не используется re модуля:

from collections import defaultdict 
import string 

# Only process words at least a minimum number of letters long. 
MIN_WORD_LEN = 3 

def find_words(line, min_word_len=MIN_WORD_LEN): 
    # Remove punctuation and all whitespace characters other than spaces. 
    line = line.translate(None, string.punctuation + '\t\r\n') 
    return (word for word in line.split(' ') if len(word) >= min_word_len) 

def make_index(input_file): 
    index = defaultdict(set) 

    for line_num, line in enumerate(input_file, start=1): 
     for word in find_words(line.lower()): 
      index[word].add(line_num) # Ensure line number is in word's set. 

    # Convert result into a regular dictionary of simple sequence values. 
    return {word:tuple(line_nums) for word, line_nums in index.iteritems()} 

В любом случае, функция make_index() может быть использована и вывод результатов в двух столбцах, как это:

with open('StoryTime.txt', 'rt') as story_file: 
    index = make_index(story_file) 

longest_word = max((len(word) for word in index)) 
for word, line_nums in sorted(index.iteritems()): 
    print '{:<{}} {}'.format(word, longest_word, line_nums) 

В качестве тестового примера Я использовал следующий отрывок (обратите внимание, что слово «die» находится в последней строке дважды):

Now the serpent was more subtle than any beast of the field which 
the LORD God had made. And he said unto the woman, Yea, hath God said, 
Ye shall not eat of every tree of the garden? And the woman said 
unto the serpent, We may eat of the fruit of the trees of the garden: 
But of the fruit of the tree which is in the midst of the garden, 
God hath said, Ye shall not eat of it, neither shall ye touch it, lest 
ye die, or we all die. 

и получить следующие результаты:

all  (7,) 
and  (2, 3) 
any  (1,) 
beast (1,) 
but  (5,) 
die  (7,) 
eat  (3, 4, 6) 
every (3,) 
field (1,) 
fruit (4, 5) 
garden (3, 4, 5) 
god  (2, 6) 
had  (2,) 
hath (2, 6) 
lest (6,) 
lord (2,) 
made (2,) 
may  (4,) 
midst (5,) 
more (1,) 
neither (6,) 
not  (3, 6) 
now  (1,) 
said (2, 3, 6) 
serpent (1, 4) 
shall (3, 6) 
subtle (1,) 
than (1,) 
the  (1, 2, 3, 4, 5) 
touch (6,) 
tree (3, 5) 
trees (4,) 
unto (2, 4) 
was  (1,) 
which (1, 5) 
woman (2, 3) 
yea  (2,) 
+0

Есть ли способ сделать это без импорта модуля? – Dragonchicken

+0

Несомненно ... см. Обновление. Я также модифицировал его, поэтому индекс слова нечувствителен к регистру. – martineau

+0

P.S. Если вы нашли мой ответ полезным, подумайте об этом: [_Что делать, когда кто-то отвечает на мой вопрос? _] (Http://stackoverflow.com/help/someone-answers) – martineau

0

Прежде всего, я бы воспользовался regex, чтобы найти слова. Чтобы удалить повторы строк, просто сделайте set() из списка (или используйте set). «Довольно формат» можно с str.format() из 2.6+ (других решений tabulate, clint, ..., column -t)

import re 
data = {} 

word_re = re.compile('[a-zA-Z]{4,}') 


with open('/tmp/txt', 'r') as f: 
    current_line = 1 
    for line in f: 
     words = re.findall(word_re, line) 
     for word in words: 
      if word in data.keys(): 
       data[word].append(current_line) 
      else: 
       data[word] = [current_line] 
     current_line += 1 


for word, lines in data.iteritems(): 
    print("{: >20} {: >20}".format(word, ", ".join([str(l) for l in set(lines)]))) 
+0

Можно ли не использовать регулярное выражение, чтобы сделать это? – Dragonchicken

 Смежные вопросы

  • Нет связанных вопросов^_^