在Python中对列表项进行分类

2024-03-28 08:42:06 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,我试图创建一个列表(myClassifier),根据列表(txtList)中存储的每个文本文件(txentry)是否包含坏单词(badWord)列表中存储的坏单词,为其附加一个分类(“bad”/“good”)。你知道吗

txtList = ['mywords.txt', 'apple.txt, 'banana.txt', ... , 'something.txt']
badWord = ['pie', 'vegetable, 'fatigue', ... , 'something']

txentry只是一个占位符,实际上我只想遍历txtList中的每个条目。你知道吗

作为回应,我生成了以下代码:

for txtEntry in txtList:
    if badWord in txtEntry:
        myClassifier += 'bad'
    else:
        myClassifier += 'good'

但是,我收到了TypeError:'in'需要字符串作为左操作数,而不是list。你知道吗

我猜badWord应该是一个字符串,而不是一个列表,尽管我不知道如何才能让它工作。你知道吗

否则我怎么能做到这一点呢?你知道吗


Tags: 字符串intxt列表分类单词somethingbad
3条回答

要找出哪些文件中有坏话,可以:

import re
from pprint import pprint

filenames = ['mywords.txt', 'apple.txt', 'banana.txt', 'something.txt']
bad_words = ['pie', 'vegetable', 'fatigue', 'something']

classified_files = {} # filename -> good/bad    
has_bad_words = re.compile(r'\b(?:%s)\b' % '|'.join(map(re.escape, bad_words)),
                           re.I).search
for filename in filenames:
    with open(filename) as file:
         for line in file:
             if has_bad_words(line):
                classified_files[filename] = 'bad'
                break # go to the next file
         else: # no bad words
             classified_files[filename] = 'good'

pprint(classified_files)

如果要将单词的不同屈折形式标记为'bad',例如cactusbad_words中,并且要排除cacti(复数形式),那么可能需要词干分析器或更普遍的lemmatizer,例如

from nltk.stem.porter import PorterStemmer # $ pip install nltk

stemmer = PorterStemmer()
print(stemmer.stem("pies")) 
# -> pie

或者

from nltk.stem.wordnet import WordNetLemmatizer

lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('cacti'))
# -> cactus

注意:您可能需要import nltk; nltk.download()来下载wordnet数据。你知道吗

可能更简单,只需将所有可能的形式(如piescacti)直接添加到bad_words列表中即可。你知道吗

这个

if badWord in txtEntry:

测试badWord是否等于textEntry中的任何子字符串。因为它是一个列表,所以它没有也不能-您需要做的是分别检查badWord中的每个字符串。最简单的方法是使用函数any。不过,您确实需要将txtEntry标准化,因为(如注释中所述)您关心的是匹配精确的单词,而不仅仅是子字符串(这些子字符串是string in string测试的),而且您(可能)希望搜索不区分大小写:

import re

for txtEntry in txtList:
    # Ensure that `word in contents` doesn't give 
    # false positives for substrings - avoid eg, 'ass in class'
    contents = [w.lower() for w in re.split('\W+', txtEntry)]

    if any(word in contents for word in badWord):
         myClassifier.append('bad')
    else:
         myClassifer.append('good')

请注意,与其他答案一样,我使用了list.append方法而不是+=将字符串添加到列表中。如果您使用+=,您的列表将变成这样:['g', 'o', 'o', 'd', 'b', 'a', 'd']而不是['good', 'bad']。你知道吗

根据对问题的评论,如果您想在仅存储文件名时检查文件的内容,则需要稍微调整此项—您需要调用open,然后需要对内容进行测试—但测试和规范化保持不变:

import re

for txtEntry in txtList:
    with open(txtEntry) as f:
        # Ensure that `word in contents` doesn't give 
        # false positives for substrings - avoid eg, 'ass in class'
        contents = [w.lower() for w in re.split('\W+', f.read())]
    if any(word in contents for word in badWord):
        myClassifier.append('bad')
    else:
        myClassifer.append('good')   

这些循环都假设,与示例数据一样,badWord中的所有字符串都是小写的。你知道吗

你也应该在badWord项上循环,对于每个项,你应该检查它是否存在于txentry中。你知道吗

for txtEntry in txtList:
    if any(word in txtEntry for word in badWord)::
        myClassifier.append("bad") # append() is better and will give you the right output as += will add every letter in "bad" as a list item. or you should make it myClassifier += ['bad']
    else:
        myClassifier.append("good")

感谢@lvc评论

相关问题 更多 >