python 中说话人分隔正文的循环索引错误

Index error in loop to separate body of text by speaker in python

我有一个文本语料库,其形式如下:

JOHN: Thanks for coming, everyone!

(EVERYONE GRUMBLES)

ROGER: They're really glad to see you, huh?

DAVIS: They're glad to see the both of you.

为了分析文本,我想按说话者将其分成块。我想留住约翰和罗杰,但不想留住戴维斯。我还想找出每个人的演讲中某些短语(如(EVERYONE GRUMBLES))出现的次数。

我的第一个想法是使用 NLTK,所以我将其导入并使用以下代码删除所有标点符号并对文本进行标记化,以便语料库中的每个单词都成为一个单独的标记:

f = open("text.txt")
raw_t = f.read()
tokenizer = RegexpTokenizer(r'\w+')
tokens = tokenizer.tokenize(raw_t.decode('utf-8'))
text = nltk.Text(tokens)

然后,我想我可以创建一个全局列表,其中包括约翰和罗杰说话的所有实例。

我想我会先看看文本语料库中的每个单词是否都是大写的,并且在可接受的名称列表中,如果是,我会检查每个后续单词,直到下一个术语出现这都是大写字母,并且在可接受的名称列表中找到。然后我会添加从演讲者姓名的初始实例到比下一位演讲者姓名少一个词的所有单词,并将这一系列 tokens/words 添加到我的全局列表中。

我写过:

k = 0
i = 0
j = 1

names =["JOHN","ROGER"]
global_list =[]

for i in range(len(text)):
    if (text[i].isupper() and text[i] in names):
        for j in range(len(text)-i):
            if (text[i+j].isupper() and text[i+j] in names):
                global_list[k] = text[i:(j-1)]
                k+=1
            else: j+=1
    else: i+=1

不幸的是,这不起作用,我收到以下索引错误:

IndexError                                Traceback (most recent call last)
<ipython-input-49-97de0c68b674> in <module>()
      6         for j in range(len(text)-i):
      7             if (text[i+j].isupper() and text[i+j] in names):
----> 8                 list_speeches[k] = text[i:(j-1)]
      9                 k+=1
     10             else: j+=1

IndexError: list assignment index out of range
    
        

我觉得我在这里搞砸了一些非常基本的事情,但这并不是我收到此索引错误的确切原因。任何人都可以阐明这一点吗?

将文本分成 re.split(r"\n\s*\n", text) 的段落,然后检查每个段落的第一个单词,看看谁在说话。不用担心 nltk-- 你还没有用过,也不需要。

好的,经过一番深入研究后发现了这一点。问题中提到的初始循环有一大堆无关的内容,所以我将其简化为:

names =["JOHN","ROGER"]
global_list = []
i = 0

for i in range(len(text)):
    if (text[i].isupper()) and (text[i] in names):
        j=0
        while (text[i+j].islower()) and (text[i+j] not in names):
            j+=1
        global_list.append(text[i:(j-1)])

这生成了一个列表,但有问题的是,此列表中的每个项目都是由从名称到文档末尾的单词组成的。因为每个项目都以适当的名称开始,并以文本语料库的最后一个单词结束,所以很容易通过从中减去以下片段的长度来导出每个片段的长度:

x=1
new_list = range(len(global_list)-1)
for x in range(len(global_list)):
    if x == len(global_list):
        new_list[x-1] = global_list[x]
    else:
        new_list[x-1] = global_list[x][:(len(global_list[x])-len(global_list[x+1]))]

(x设置为1是因为原代码给了我两次第一个speaker的内容)

这一点也不漂亮,但它最终起作用了。如果有人有更漂亮的方法来做这件事——我确信它存在,因为我认为我搞砸了初始循环——我很乐意看到它。