2015-07-09 3 views
0

Моя цель - рассчитать количество слов. Когда я запускаю мой код я полагаю,:Почему мой код записывается в файл только тогда, когда я запускаю его во второй раз?

  1. чтения в строках из файла
  2. раздельных каждая строка в словах
  3. добавить эти слова в словарь
  4. ключей сортировки и добавить их в список
  5. написать строку, состоящую из ключей и соответствующих значений в файл

Когда я запускаю код в первый раз, он делает не пишу что-нибудь в файле, но я вижу результат на моем экране. Файл пуст. Только когда я запускаю код второй раз, я вижу, что содержимое записывается в файл.

Почему это происходит?

#read in the file 
fileToRead = open('../folder/strings.txt') 
fileToWrite = open('../folder/count.txt', 'w') 

d = {} 
#iterate over every line in the file 
for line in fileToRead: 
    listOfWords = line.split() 
    #iterate over every word in the list 
    for word in listOfWords: 
     if word not in d: 
      d[word] = 1 
     else: 
      d[word] = d.get(word) + 1 
#sort the keys 
listF = sorted(d) 

#iterate over sorted keys and write them in the file with appropriate value 
for word in listF: 
    string = "{:<18}\t\t\t{}\n".format(word, d.get(word)) 
    print string 
    fileToWrite.write(string) 
+4

ли вы когда-либо закрыть файлы? – Kevin

ответ

0

Минималистичный версия:

import collections 

with open('strings.txt') as f: 
    d = collections.Counter(s for line in f for s in line.split()) 

with open('count.txt', 'a') as f: 
    for word in sorted(d.iterkeys()): 
     string = "{:<18}\t\t\t{}\n".format(word, d[word]) 
     print string, 
     f.write(string) 
+0

А, нет, вы правы. Вы строите генератор слов и передаете его в «Счетчик». Я ошибся, чтобы передать каждое слово индивидуальному «Counter» (как мой код сделал это: 'd = sum ([Counter (line.split()) для строки в f])') –

+0

Оба работали на меня. Спасибо. Я все еще не могу привыкнуть писать эти утверждения: «s для строки в f для s в строке .split()». Но я все еще хочу знать, почему сумма в делах Адама не срабатывала. Предполагалось. Постскриптум Оба ответа велики. Извините, я не могу выбрать два из лучших. – Sergey

0

изменения Пара, это кажется, вы имели в виду «а» (добавить в файл) вместо «W» перезапись файла каждый раз, когда в открытом («count.txt», «а»). Также попробуйте использовать инструкцию для чтения и записи файлов, поскольку она автоматически закрывает дескриптор файла после завершения чтения/записи.

#read in the file 
fileToRead = open('strings.txt') 

d = {} 
#iterate over every line in the file 
for line in fileToRead: 
    listOfWords = line.split() 
    #iterate over every word in the list 
    for word in listOfWords: 
     if word not in d: 
      d[word] = 1 
     else: 
      d[word] = d.get(word) + 1 
#sort the keys 
listF = sorted(d) 

#iterate over sorted keys and write them in the file with appropriate value 
with open('count.txt', 'a') as fileToWrite: 
    for word in listF: 
     string = "{:<18}\t\t\t{}\n".format(word, d.get(word)) 
     print string, 
     fileToWrite.write(string) 
0

Когда вы file.write(some_data), он записывает данные в буфер, но не в файл. Он сохраняет файл только на диске, когда вы делаете file.close().

f = open('some_temp_file.txt', 'w') 

f.write("booga boo!") 
# nothing written yet to disk 

f.close() 
# flushes the buffer and writes to disk 

Лучший способ сделать это - сохранить путь в переменной, а не в файловом объекте. Затем вы можете открыть файл (и закрыть его снова) по требованию.

read_path = '../folder/strings.txt' 
write_path = '../folder/count.txt' 

Это также позволяет использовать with ключевое слово, которое обрабатывает открытие файла и закрытие гораздо более элегантно.

read_path = '../folder/strings.txt' 
write_path = '../folder/count.txt' 

d = dict() 

with open(read_path) as inf: 
    for line in inf: 
     for word in line.split() 
      d[word] = d.get(word, 0) + 1 
      # remember dict.get's default value! Saves a conditional 

# since we've left the block, `inf` is closed by here 

sorted_words = sorted(d) 

with open(write_path, 'w') as outf: 
    for word in sorted_words: 
     s = "{:<18}\t\t\t{}\n".format(word, d.get(word)) 
     # don't shadow the stdlib `string` module 
     # also: why are you using both fixed width AND tab-delimiters in the same line? 
     print(s) # not sure why you're doing this, but okay... 
     outf.write(s) 
# since we leave the block, the file closes automagically. 

Тем не менее, есть несколько вещей, которые вы могли бы сделать, чтобы сделать это немного лучше вообще. Во-первых: подсчет количества вещей в контейнере - это задание для collections.Counter.

In [1]: from collections import Counter 

In [2]: Counter('abc') 
Out[2]: Counter({'a': 1, 'b': 1, 'c': 1}) 

и Counter s могут быть добавлены вместе с ожидаемым поведением

In [3]: Counter('abc') + Counter('cde') 
Out[3]: Counter({'c': 2, 'a': 1, 'b': 1, 'd': 1, 'e': 1}) 

, а также сортируются так же, как вы бы сортировать словарь с ключами

In [4]: sorted((Counter('abc') + Counter('cde')).items(), key=lambda kv: kv[0]) 
Out[4]: [('a', 1), ('b', 1), ('c', 2), ('d', 1), ('e', 1)] 

Put те все вместе и вы можете сделать что-то вроде:

from collections import Counter 

read_path = '../folder/strings.txt' 
write_path = '../folder/count.txt' 

with open(read_path) as inf: 
    results = sum([Counter(line.split()) for line in inf]) 

with open(write_path, 'w') as outf: 
    for word, count in sorted(results.items(), key=lambda kv: kv[0]): 
     s = "{:<18}\t\t\t{}\n".format(word, count) 
     outf.write(s) 
+0

Спасибо.Но эта строка: results = sum ([Counter (line.split()) для строки в inf]) вызывает ошибку: неподдерживаемый тип операндов для +: 'int' и 'Counter'. Когда я удаляю sum() и печатаю, получается результат некоторого количества счетчиков. Сумма должна работать, но это не так. Спасибо за объяснение прилавков. Я не знал, что могу их суммировать. – Sergey

+0

Выражение '[Counter (line.split()) для строки в inf]' создает список объектов 'Counter', которые не могут быть' sum'-med с начальным нулевым значением по умолчанию. Необходимо указать явное начальное значение, поэтому рабочая версия: 'sum ([Counter (line.split()) для строки в inf], Counter())'. – dlask

+0

Хм, я уверен, что проверял его, но у меня нет времени на это. Я полагаю, вы могли бы также выполнить функцию functools.reduce (operator.add, [Counter (line.split()) для ...]) ' –

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