2013-04-30 3 views
2

Я пытаюсь подсчитать количество символов пунктуации, появляющихся в романе. Например, я хочу найти вхождения вопросительных знаков и периодов вместе со всеми другими не алфавитно-цифровыми символами. Затем я хочу вставить их в файл csv. Я не уверен, как делать регулярное выражение, потому что у меня нет такого большого опыта работы с python. Кто-нибудь может мне помочь?Подсчет пунктуации в тексте с использованием Python и regex

texts=string.punctuation 
counts=dict(Counter(w.lower() for w in re.findall(r"\w+", open(cwd+"/"+book).read()))) 
writer = csv.writer(open("author.csv", 'a')) 
writer.writerow([counts.get(fieldname,0) for fieldname in texts]) 
+0

Не делайте подсчет частоты с регулярным выражением. Просто зациклируйте символ по символу и отфильтруйте буквы, цифры и пробелы, и нажмите остальные в dict для подсчета частоты. Или другим способом является замена всех букв, цифр и пробелов, а затем цикл через оставшуюся строку (которая является более чистой). – nhahtdh

+0

Вы побеждаете цель счетчика, опуская его инициализацию в словарь, а затем вызывая '.get (x, 0)', когда вы могли просто оставить его в качестве счетчика, который возвращает 0 для отсутствующих элементов – jamylak

+0

, t нужно регулярное выражение, просто проверьте, является ли символ 'in' строкой префикса строки [string module] (http://docs.python.org/2/library/string.html#string.пунктуация) при повторении по роману –

ответ

6
In [1]: from string import punctuation 

In [2]: from collections import Counter 

In [3]: counts = Counter(open('novel.txt').read()) 

In [4]: punctuation_counts = {k:v for k, v in counts.iteritems() if k in punctuation} 
+2

Единственная реальная проблема, с которой я сталкиваюсь, заключается в том, что вы сразу загружаете весь роман в память! 'open ('novel.txt'). read()' Я могу представить, что любой ролик среднего размера сделает эту операцию довольно интенсивной. – jamylak

+1

@jamylak, [целая Библия короля Джеймса] (http://printkjv.ifbweb.com/#downloads) - всего несколько мегабайт. (4,4 МБ при распаковке). –

0

Код, который у вас есть, очень близок к тому, что вам нужно, если вы считаете слова. Если вы пытаетесь считать слова, единственное изменение вы должны сделать, вероятно, будет изменить последнюю строку следующим образом:

writer.writerows(counts.items()) 

К сожалению, вы не пытаетесь считать слова здесь. Если вы ищете количество одиночных символов, я бы избегал использования регулярных выражений и перешел прямо к count. Ваш код может выглядеть следующим образом:

book_text = open(cwd+"/"+book).read() 
counts = {} 
for character in texts: 
    counts[character] = book_text.count(character) 
writer.writerows(counts.items()) 

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

0

Использование проклятья:

import curses.ascii 
str1 = "real, and? or, and? what." 
t = (c for c in str1 if curses.ascii.ispunct(c)) 
d = dict() 
for p in t: 
    d[p] = 1 if not p in d else d[p] + 1 for p in t 
+0

Нет необходимости в этом цикле 'for'; просто используйте 'd = Counter (t)'. Кроме того, вы можете использовать «map», а не это выражение генератора, хотя это может быть и не так очевидно. – icktoofay

+0

Попробуйте использовать 'str' как имя переменной, так как вам может понадобиться использовать' str (1) 'позже в вашей программе, и теперь вы не можете – jamylak

3
from string import punctuation 
from collections import Counter 

with open('novel.txt') as f: # closes the file for you which is important! 
    c = Counter(c for line in f for c in line if c in punctuation) 

Это также позволяет избежать загрузки всего романа в памяти сразу.

Btw это то, что string.punctuation выглядит следующим образом:

>>> punctuation 
'!"#$%&\'()*+,-./:;<=>[email protected][\\]^_`{|}~' 

Вы можете добавить или умаляет символы здесь в зависимости от ваших потребностей.

Также Counter определяет __missing__ с просто return 0. Таким образом, вместо down-initializing его в словарь, а затем вызывая .get(x, 0). Просто оставьте это как счетчик и получите доступ к нему, как c[x], если его не существует, его счет равен 0. Я не уверен, почему у каждого есть внезапное желание понизить все их Counter s до dict s только из-за страшного поиска Counter([...]) вы видите, когда вы печатаете один, когда на самом деле Counter s также являются словарями и заслуживают уважения.

writer.writerow([counts.get(c, 0) for c in punctuation]) 

Если оставить свой счетчик, вы можете просто сделать это:

writer.writerow([counts[c] for c in punctuation]) 

, и это было гораздо проще.

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