【问题标题】:Empty output after appending a list附加列表后的空输出
【发布时间】:2016-01-19 12:34:04
【问题描述】:
r = ","
x = ""
output = list()
import string

def find_word(filepath,keyword):
    doc = open(filepath, 'r')

    for line in doc:
        #Remove all the unneccessary characters
        line = line.replace("'", r)
        line = line.replace('`', r)
        line = line.replace('[', r)
        line = line.replace(']', r)
        line = line.replace('{', r)
        line = line.replace('}', r)
        line = line.replace('(', r)
        line = line.replace(')', r)
        line = line.replace(':', r)
        line = line.replace('.', r)
        line = line.replace('!', r)
        line = line.replace('?', r)
        line = line.replace('"', r)
        line = line.replace(';', r)
        line = line.replace(' ', r)
        line = line.replace(',,', r)
        line = line.replace(',,,', r)
        line = line.replace(',,,,', r)
        line = line.replace(',,,,,', r)
        line = line.replace(',,,,,,', r)
        line = line.replace(',,,,,,,', r)
        line = line.replace('#', r)
        line = line.replace('*', r)
        line = line.replace('**', r)
        line = line.replace('***', r)

        #Make the line lowercase
        line = line.lower()

        #Split the line after every r (comma) and name the result "word"
        words = line.split(r)

        #if the keyword (also in lowercase form) appears in the before created words list
        #then append the list output by the whole line in which the keyword appears

        if keyword.lower() in words:
            output.append(line)

    return output

print find_word("pg844.txt","and")

这段代码的目标是在一个文本文件中搜索某个关键字,比如“and”,然后将找到该关键字的整行放入一个类型为 (int,string) 的列表中。 int 应该是行号,字符串是上面提到的其余整行。

我仍在处理行号问题 - 所以对此没有任何疑问。但问题是:输出为空。即使我附加一个随机字符串而不是行,我也没有得到任何结果。

如果我使用

if keyword.lower() in words:
        print line

我得到了所有需要的行,其中出现了关键字。但我就是无法将它放入输出列表中。

我试图搜索的文本文件:http://www.gutenberg.org/cache/epub/844/pg844.txt

【问题讨论】:

  • 你是怎么调用函数的?
  • 抱歉,我错过了最后一段代码。我编辑了原始帖子。
  • 在文本文件中搜索某个关键字 - 有很多代码要做for line_num, line in enumerate(open('filename')): if keyword.lower in line: output.append((line_num, line))
  • @TessellatingHeckler: if keyword.lower() in line.lower()
  • @TessellatingHeckler:另外,'and' in 'band,hand' 给出的结果与'and' in 'band,hand'.split(',') 不同。拆分允许匹配仅在整个单词上。

标签: python string list output


【解决方案1】:

请使用正则表达式。请参阅Regex in Python 的一些文档。替换每个字符/字符集是令人困惑的。列表和 .append() 的使用看起来是正确的,但也许可以考虑在 for 循环中调试您的 line 变量,偶尔打印它以确保它的值是您想要的。

pyInProgress 的回答很好地说明了全局变量,尽管没有对其进行测试,如果使用 output 返回变量而不是全局 output 变量,我不相信它是必需的。如果您需要有关全局变量的更多信息,请参阅this StackOverflow post

【讨论】:

    【解决方案2】:

    遍历string.punctuation 以在遍历行之前删除所有内容

    import string, re
    
    r = ','
    
    def find_word(filepath, keyword):
    
        output = []
        with open(filepath, 'rb') as f:
            data = f.read()
            for x in list(string.punctuation):
                if x != r:
                    data = data.replace(x, '')
            data = re.sub(r',{2,}', r, data, re.M).splitlines()
    
        for i, line in enumerate(data):
            if keyword.lower() in line.lower().split(r):
                output.append((i, line))
        return output
    
    print find_word('pg844.txt', 'and')
    

    【讨论】:

    • 你为什么要这样做而不是使用正则表达式?
    • 因为我是一个肮脏的农民。 r'{0}|{1}'.format(',{2,}', '|'.join(list(string.punctuation)))
    【解决方案3】:

    由于output = list() 位于代码的顶层并且不在函数内部,因此它被视为全局变量。 要在函数中编辑全局变量,必须首先使用 global 关键字。

    例子:

    gVar = 10
    
    def editVar():
        global gVar
        gVar += 5
    

    因此,要在函数find_word() 中编辑变量output,您必须在为其赋值之前输入global output

    应该是这样的:

    r = ","
    x = ""
    output = list()
    import string
    
    def find_word(filepath,keyword):
        doc = open(filepath, 'r')
    
        for line in doc:
            #Remove all the unneccessary characters
            line = line.replace("'", r)
            line = line.replace('`', r)
            line = line.replace('[', r)
            line = line.replace(']', r)
            line = line.replace('{', r)
            line = line.replace('}', r)
            line = line.replace('(', r)
            line = line.replace(')', r)
            line = line.replace(':', r)
            line = line.replace('.', r)
            line = line.replace('!', r)
            line = line.replace('?', r)
            line = line.replace('"', r)
            line = line.replace(';', r)
            line = line.replace(' ', r)
            line = line.replace(',,', r)
            line = line.replace(',,,', r)
            line = line.replace(',,,,', r)
            line = line.replace(',,,,,', r)
            line = line.replace(',,,,,,', r)
            line = line.replace(',,,,,,,', r)
            line = line.replace('#', r)
            line = line.replace('*', r)
            line = line.replace('**', r)
            line = line.replace('***', r)
    
            #Make the line lowercase
            line = line.lower()
    
            #Split the line after every r (comma) and name the result "word"
            words = line.split(r)
    
            #if the keyword (also in lowercase form) appears in the before created words list
            #then append the list output by the whole line in which the keyword appears
    
            global output
            if keyword.lower() in words:
                output.append(line)
    
        return output
    

    以后尽量远离全局变量,除非你绝对需要它们。他们可能会变得一团糟!

    【讨论】:

    • 不正确。您可以在不使用global 的情况下对全局变量调用变异方法。当你想 assign 给一个全局变量时,你只需要global,否则赋值会创建一个同名的局部变量。
    • 有趣的地方。我无法解释为什么这个解决方案对 neacal 有效。有什么想法吗?
    • 取决于他使用的方法。他返回列表并定义了一个全局变量。如果他在方法中添加global,那么他可以看到全局对象上的这些更改。但是,如果他使用返回值,则不需要添加global
    猜你喜欢
    • 2021-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 2019-02-12
    • 2015-10-21
    • 1970-01-01
    • 2020-11-02
    相关资源
    最近更新 更多