Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python str.split()返回AttributeError:';非类型';对象没有属性';拆分';_Python_Split_Tokenize_Attributeerror - Fatal编程技术网

Python str.split()返回AttributeError:';非类型';对象没有属性';拆分';

Python str.split()返回AttributeError:';非类型';对象没有属性';拆分';,python,split,tokenize,attributeerror,Python,Split,Tokenize,Attributeerror,我很难在上拆分字符串\n。我将一个约138M长的日语字符串传递到标记器/单词标记器中,并得到“AttributeError:'NoneType'对象没有属性'split'”错误 标记器的名称是MeCab,它的作用是获取一个字符串,查找其中的单词,然后返回一个具有单词特征(名词、粒子、阅读等)的字符串。字符串中标记器标记的单词被“\n”拆分,因此我想使用新行将其拆分为一个列表 字符串的前25个字符: str_text[:25] 输出: 'このページは以下にある削除依頼の議論を保存したもの' L

我很难在上拆分字符串\n。我将一个约138M长的日语字符串传递到标记器/单词标记器中,并得到“AttributeError:'NoneType'对象没有属性'split'”错误

标记器的名称是MeCab,它的作用是获取一个字符串,查找其中的单词,然后返回一个具有单词特征(名词、粒子、阅读等)的字符串。字符串中标记器标记的单词被“\n”拆分,因此我想使用新行将其拆分为一个列表

字符串的前25个字符:

str_text[:25]
输出:

'このページは以下にある削除依頼の議論を保存したもの'
Last block, chief! 133500000 : 133600000
CPU times: user 3min 7s, sys: 2.83 s, total: 3min 10s
Wall time: 3min 10s

当我使用下面的代码拆分前100万个字符时,我没有错误,但是当我将其扩展到1000万个字符时,我得到了上面提到的错误

前25个字符的编码和输出:

import MeCab

#opening the file containing the long string with Japanese text
file = open('output_text.txt')
str_text = file.read()

#passing string into the MeCab tokenizer/tagger and splitting the long string into a list based on
tagger = MeCab.Tagger()
words = tagger.parse(str_text[:25]).split('\n')[:-2] #last two entries are just some tagger info

for word in words:
    temp_str = word.split('\t')
    print(temp_str)
输出(第一个元素是单词,第二个元素包含关于单词的信息):

我替换了str_文本文件中出现的所有“\n”,因此这不是问题所在。字符串不能通过一个字符传递到标记器/标记器中,因为它根据长字符串确定str是单词。它对前100万个字符有效,但在10万个字符时失败,这一事实告诉我,这可能是一千万次中的一次。我已经寻找了几个小时的解决方案,但找不到任何有助于解决这个问题的方法。我可能会将字符串分为100万个块传递,但在可能有解决方案的情况下,丢失那么多数据是错误的

任何帮助都将不胜感激

@伊凡利马先生,谢谢你修改了我文章的语法

@Karl Knechtel在评论中的建议导致了我问题的解决。谢谢大家!

对于那些感兴趣的人,以下是最终有效的完整代码:

%%time

#load the txt file with Japanese characters:
file = open('output_text.txt')
str_text = file.read()

#boundries for the text blocks used in the below for loop
lower = 0
upper = 100000

#dictionary for words and kanji characters
counts_words = dict()
counts_kanji = dict()

word_counter = 0

#tokenizer/tagger
tagger = MeCab.Tagger()

#splits strings into a list, used for words that have more than one character to get individual characters
def splitter(word): 
    return list(word)

#break condition for the loop
condition = 'no'

while True:
    if condition == 'yes':
        break

    #this is for the last block of 100k increments
    elif lower > 133400001:
        #initiate break condition
        condition = 'yes'
        words = tagger.parse(str_text[lower:]).split('\n')[:-2]
        print('Last block, chief!',lower,':',upper)
        lower+=100000
        upper+=100000
        for word in words:
            temp_str = word.split('\t')
            word_counter+=1
            counts_words[temp_str[0]+' '+temp_str[1]] = counts_words.get(temp_str[0]+' '+temp_str[1], 0) + 1
            if len(temp_str[0])>1:
                for i in splitter(temp_str[0]):
                    counts_kanji[i] = counts_kanji.get(i, 0) + 1
                    break
            else:
                counts_kanji[temp_str[0]] = counts_kanji.get(temp_str[0], 0) + 1
                break

    else:
        #pass string 100k long string block into a tokenizer/tagger
        words = tagger.parse(str_text[lower:upper]).split('\n')[:-2]
        
        #increment the lower and upper boundries of the str blocks
        lower+=100000
        upper+=100000
        
        #iterate through each word parsed by the tokenizer
        for word in words:
            temp_str = word.split('\t') #split each word data by tab, [word, info]
            word_counter+=1 #count number of words
            
            #check if the entry exists in the words dict, either add or increment the counts
            counts_words[temp_str[0]+' '+temp_str[1]] = counts_words.get(temp_str[0]+' '+temp_str[1], 0) + 1
            
            #check if the word has more than one character, if yes split it and add each character to the kanji dict
            if len(temp_str[0])>1:
                for i in splitter(temp_str[0]):
                    #check if the entry exists in the words dict, either add or increment the counts
                    counts_kanji[i] = counts_kanji.get(i, 0) + 1
            else:
                counts_kanji[temp_str[0]] = counts_kanji.get(temp_str[0], 0) + 1
输出:

'このページは以下にある削除依頼の議論を保存したもの'
Last block, chief! 133500000 : 133600000
CPU times: user 3min 7s, sys: 2.83 s, total: 3min 10s
Wall time: 3min 10s

我是mecab-python3的开发者

我想你可能已经就此给我发了邮件,但请不要传递MeCab 1M字符串。它是在假设输入是一个句子的情况下发展起来的。它很健壮,并且可以处理更长的字符串——例如,你在处理段落时不会遇到问题——但你基本上是在毫无益处地进入未经测试的领域

在将输入文本传递给MeCab之前,将其拆分为段落或句子

此外,关于这一点:

我可能会将字符串分为100万个块传递,但在可能有解决方案的情况下,丢失那么多数据是错误的


传递较短的字符串不会丢失任何数据。我不确定你在这里指的是什么。

我是mecab-python3的开发者

我想你可能已经就此给我发了邮件,但请不要传递MeCab 1M字符串。它是在假设输入是一个句子的情况下发展起来的。它很健壮,并且可以处理更长的字符串——例如,你在处理段落时不会遇到问题——但你基本上是在毫无益处地进入未经测试的领域

在将输入文本传递给MeCab之前,将其拆分为段落或句子

此外,关于这一点:

我可能会将字符串分为100万个块传递,但在可能有解决方案的情况下,丢失那么多数据是错误的


传递较短的字符串不会丢失任何数据。我不确定您在这里指的是什么。

“当我使用下面的代码拆分前100万个字符时,我没有错误,但当我将其扩展到1000万个字符时,我得到了上面提到的错误。”您是否尝试过在块中专门查看100万到200万个字符等?如果有一个特定的块似乎导致了问题,那么您可以进一步缩小它的范围,然后检查导致问题的实际文本是什么。您应该将生成异常的行放在try/except块中。在except块中,检查word变量并确认它实际上是None。事实上,如果你用
作为索引开始循环,单词在枚举中(单词):
,你将有一个失败单词的索引号。根据Karl的建议,我刚刚发现300-400万块中存在一个错误,所以我想我会继续缩小块/环,直到找到罪魁祸首。谢谢两位。您可以将其放入
try..except
块中,然后打印出属于
except
的内容。好的,看起来标记器只是不喜欢字符串块来生成一定数量的单词。该程序在300-400万个字符块中崩溃的原因不是因为它不喜欢那里的某些字符,而是因为它产生的单词比其他100万个字符长的块多。当我把它分割成100K个字符块时,一切都处理得很好。我现在似乎无法打破我的while循环,但哦,好吧,我会找到答案的@卡勒克内切特尔:谢谢你的帮助。你的建议促成了解决方案。你能把它作为一个答案,这样我就可以相信你了吗?“当我使用下面的代码拆分前100万个字符时,我没有错误,但当我将其扩展到1000万时,我得到了上面提到的错误。”你有没有试着专门在块中查看100万到200万个字符等?如果有一个特定的块似乎导致了问题,那么您可以进一步缩小它的范围,然后检查导致问题的实际文本是什么。您应该将生成异常的行放在try/except块中。在except块中,检查word变量并确认它实际上是None。事实上,如果你用
作为索引开始循环,单词在枚举中(单词):
,你将有一个失败单词的索引号。使用Karl的建议,我刚刚发现一个错误在300-400万块中