我开始学习Python,我正在尝试编写一个程序来导入一个文本文件,计算单词的总数,计算特定段落中的单词数(由每个参与者说,由'P1','P2‘等描述),排除这些单词(即'P1‘等)从我的字数,并分别打印段落。
多亏了@James Hurford,我得到了以下代码:
words = None
with open('data.txt') as f:
words = f.read().split()
total_words = len(words)
print 'Total words:', total_words
in_para = False
para_type = None
paragraph = list()
for word in words:
if ('P1' in word or
'P2' in word or
'P3' in word ):
if in_para == False:
in_para = True
para_type = word
else:
print 'Words in paragraph', para_type, ':', len(paragraph)
print ' '.join(paragraph)
del paragraph[:]
para_type = word
else:
paragraph.append(word)
else:
if in_para == True:
print 'Words in last paragraph', para_type, ':', len(paragraph)
print ' '.join(paragraph)
else:
print 'No words'我的文本文件如下:
P1: Bla bla bla.
P2:.
P1:。
P3: Bla.
我需要做的下一部分是总结每个参与者的单词。我只能打印它们,但是我不知道如何返回/重用它们。
我将需要一个新的变量,每个参与者的字数,我以后可以操作,除了总结每个参与者说的所有的话,例如。
P1all = sum of words in paragraph有没有办法把“you‘s”或"it's“等数成两个单词?
有什么办法解决吗?
发布于 2015-12-04 03:06:50
恭喜你用Python开始你的冒险!并不是这篇文章中的每一件事现在都有意义,但是如果它以后有帮助的话,就把它书签上书签,然后再回来。最后,您应该尝试从脚本到软件工程,以下是一些您的想法!
强大的力量带来了巨大的责任,作为Python开发人员,您需要比其他不掌握您的手并执行“好”设计的语言更加自律。
我发现从自上而下的设计开始很有帮助。
def main():
text = get_text()
p_text = process_text(text)
catalogue = process_catalogue(p_text)轰隆隆!你刚刚写了整个程序--现在你只需要回到并填空!当你这样做的时候,看起来就没那么吓人了。就我个人而言,我认为自己不够聪明,不能解决很大的问题,但我是解决小问题的专家。所以让我们一次处理一件事。我将从'process_text‘开始。
def process_text(text):
b_text = bundle_dialogue_items(text)
f_text = filter_dialogue_items(b_text)
c_text = clean_dialogue_items(f_text)我还不太清楚这些东西意味着什么,但我知道文本问题倾向于遵循一种叫做“map/ then”的模式,这意味着您对一些东西执行和操作,然后清理它并组合起来,所以我添加了一些占位符函数。如果需要的话,我可能会回去再加更多。
现在让我们来写“过程目录”。我本可以写"process_dict“,但对我来说这听起来很蹩脚。
def process_catalogue(p_text):
speakers = make_catalogue(c_text)
s_speakers = sum_words_per_paragraph_items(speakers)
t_speakers = total_word_count(s_speakers)凉爽的。不算太坏。你可能和我不同,但我认为把项目汇总起来,按段落数单词,然后计算所有的单词是有意义的。
因此,在这一点上,我可能会创建一个或两个小的'lib‘(库)模块来备份剩余的函数。为了让您能够在不担心导入的情况下运行这些文件,我将把它们都放在一个.py文件中,但最终您将学习如何将它们分解,使其看起来更好看。那我们就这么做吧。
# ------------------ #
# == process_text == #
# ------------------ #
def bundle_dialogue_items(lines):
cur_speaker = None
paragraphs = Counter()
for line in lines:
if re.match(p, line):
cur_speaker, dialogue = line.split(':')
paragraphs[cur_speaker] += 1
else:
dialogue = line
res = cur_speaker, dialogue, paragraphs[cur_speaker]
yield res
def filter_dialogue_items(lines):
for name, dialogue, paragraph in lines:
if dialogue:
res = name, dialogue, paragraph
yield res
def clean_dialogue_items(flines):
for name, dialogue, paragraph in flines:
s_dialogue = dialogue.strip().split()
c_dialouge = [clean_word(w) for w in s_dialogue]
res = name, c_dialouge, paragraph
yield resa和一个小助手函数
# ------------------- #
# == aux functions == #
# ------------------- #
to_clean = string.whitespace + string.punctuation
def clean_word(word):
res = ''.join(c for c in word if c not in to_clean)
return res因此,这可能并不明显,但这个库是作为一个数据处理管道设计的。有几种处理数据的方法,一种是流水线处理,另一种是批量处理。让我们看一看批处理。
# ----------------------- #
# == process_catalogue == #
# ----------------------- #
speaker_stats = 'stats'
def make_catalogue(names_with_dialogue):
speakers = {}
for name, dialogue, paragraph in names_with_dialogue:
speaker = speakers.setdefault(name, {})
stats = speaker.setdefault(speaker_stats, {})
stats.setdefault(paragraph, []).extend(dialogue)
return speakers
word_count = 'word_count'
def sum_words_per_paragraph_items(speakers):
for speaker in speakers:
word_stats = speakers[speaker][speaker_stats]
speakers[speaker][word_count] = Counter()
for paragraph in word_stats:
speakers[speaker][word_count][paragraph] += len(word_stats[paragraph])
return speakers
total = 'total'
def total_word_count(speakers):
for speaker in speakers:
wc = speakers[speaker][word_count]
speakers[speaker][total] = 0
for c in wc:
speakers[speaker][total] += wc[c]
return speakers所有这些嵌套字典都变得有点复杂。在实际的生产代码中,我会用一些更易读的类来替换这些类(同时添加测试和文档字符串!),但是我不想让它变得更加混乱!好吧,为了你的方便,下面是整件事的集合。
import pprint
import re
import string
from collections import Counter
p = re.compile(r'(\w+?):')
def get_text_line_items(text):
for line in text.split('\n'):
yield line
def bundle_dialogue_items(lines):
cur_speaker = None
paragraphs = Counter()
for line in lines:
if re.match(p, line):
cur_speaker, dialogue = line.split(':')
paragraphs[cur_speaker] += 1
else:
dialogue = line
res = cur_speaker, dialogue, paragraphs[cur_speaker]
yield res
def filter_dialogue_items(lines):
for name, dialogue, paragraph in lines:
if dialogue:
res = name, dialogue, paragraph
yield res
to_clean = string.whitespace + string.punctuation
def clean_word(word):
res = ''.join(c for c in word if c not in to_clean)
return res
def clean_dialogue_items(flines):
for name, dialogue, paragraph in flines:
s_dialogue = dialogue.strip().split()
c_dialouge = [clean_word(w) for w in s_dialogue]
res = name, c_dialouge, paragraph
yield res
speaker_stats = 'stats'
def make_catalogue(names_with_dialogue):
speakers = {}
for name, dialogue, paragraph in names_with_dialogue:
speaker = speakers.setdefault(name, {})
stats = speaker.setdefault(speaker_stats, {})
stats.setdefault(paragraph, []).extend(dialogue)
return speakers
def clean_dict(speakers):
for speaker in speakers:
stats = speakers[speaker][speaker_stats]
for paragraph in stats:
stats[paragraph] = [''.join(c for c in word if c not in to_clean)
for word in stats[paragraph]]
return speakers
word_count = 'word_count'
def sum_words_per_paragraph_items(speakers):
for speaker in speakers:
word_stats = speakers[speaker][speaker_stats]
speakers[speaker][word_count] = Counter()
for paragraph in word_stats:
speakers[speaker][word_count][paragraph] += len(word_stats[paragraph])
return speakers
total = 'total'
def total_word_count(speakers):
for speaker in speakers:
wc = speakers[speaker][word_count]
speakers[speaker][total] = 0
for c in wc:
speakers[speaker][total] += wc[c]
return speakers
def get_text():
text = '''BOB: blah blah blah blah
blah hello goodbye etc.
JERRY:.............................................
...............
BOB:blah blah blah
blah blah blah
blah.
BOB: boopy doopy doop
P1: Bla bla bla.
P2: Bla bla bla bla.
P1: Bla bla.
P3: Bla.'''
text = get_text_line_items(text)
return text
def process_catalogue(c_text):
speakers = make_catalogue(c_text)
s_speakers = sum_words_per_paragraph_items(speakers)
t_speakers = total_word_count(s_speakers)
return t_speakers
def process_text(text):
b_text = bundle_dialogue_items(text)
f_text = filter_dialogue_items(b_text)
c_text = clean_dialogue_items(f_text)
return c_text
def main():
text = get_text()
c_text = process_text(text)
t_speakers = process_catalogue(c_text)
# take a look at your hard work!
pprint.pprint(t_speakers)
if __name__ == '__main__':
main()因此,对于这个应用程序来说,这个脚本几乎肯定是多余的,但重点是要看到可读的、可维护的、模块化的Python代码可能是什么样子(值得怀疑)。
非常确定的输出如下所示:
{'BOB': {'stats': {1: ['blah',
'blah',
'blah',
'blah',
'blah',
'hello',
'goodbye',
'etc'],
2: ['blah',
'blah',
'blah',
'blah',
'blah',
'blah',
'blah'],
3: ['boopy', 'doopy', 'doop']},
'total': 18,
'word_count': Counter({1: 8, 2: 7, 3: 3})},
'JERRY': {'stats': {1: ['', '']}, 'total': 2, 'word_count': Counter({1: 2})},
'P1': {'stats': {1: ['Bla', 'bla', 'bla'], 2: ['Bla', 'bla']},
'total': 5,
'word_count': Counter({1: 3, 2: 2})},
'P2': {'stats': {1: ['Bla', 'bla', 'bla', 'bla']},
'total': 4,
'word_count': Counter({1: 4})},
'P3': {'stats': {1: ['Bla']}, 'total': 1, 'word_count': Counter({1: 1})}}发布于 2011-09-15 11:26:06
我需要一个新变量,为我以后可以操作的每个参与者设置单词计数。
不,您需要一个Counter (Python 2.7+,否则使用defaultdict(int))将人映射到单词计数。
from collections import Counter
#from collections import defaultdict
words_per_person = Counter()
#words_per_person = defaultdict(int)
for ln in inputfile:
person, text = ln.split(':', 1)
words_per_person[person] += len(text.split())现在,words_per_person['P1']包含了P1的字数,假设text.split()对于您来说是一个足够好的标记器。(语言学家对单词的定义存在分歧,所以你总是会得到一个近似词。)
发布于 2011-09-15 22:37:42
你可以用两个变量来做这件事。一种是为了记录谁在说话,另一种是为说话的人保留段落。为了存储段落,并将该段落属于谁,则该段落属于使用与该人作为键的dict和与该键相关的该人所说的段落的列表。
para_dict = dict()
para_type = None
for word in words:
if ('P1' in word or
'P2' in word or
'P3' in word ):
#extract the part we want leaving off the ':'
para_type = word[:2]
#create a dict with a list of lists
#to contain each paragraph the person uses
if para_type not in para_dict:
para_dict[para_type] = list()
para_dict[para_type].append(list())
else:
#Append the word to the last list in the list of lists
para_dict[para_type][-1].append(word)从这里你可以总结出这样说出的字数。
for person, para_list in para_dict.items():
counts_list = list()
for para in para_list:
counts_list.append(len(para))
print person, 'spoke', sum(counts_list), 'words'https://stackoverflow.com/questions/7429845
复制相似问题