【问题标题】:Python remove word containing "l"Python删除包含“l”的单词
【发布时间】:2016-03-01 21:55:28
【问题描述】:

我目前正在开发一个小程序。

该程序的目的是从文件中获取输入,编辑文件以删除包含字母“l”的任何单词,然后将其输出到输出文件中。

我目前的代码有效,但是它不会删除包含字母“l”的单词,只是删除字母本身。

这是我的代码

def my_main(ifile_name, ofile_name):
    ifile_name = open(ifile_name, 'r')
    ofile_name = open(ofile_name, "w+")
    delete_list = ['l']
    for line in ifile_name:
        for word in delete_list:
            line = line.replace(word, "")
        ofile_name.write(line)
    ifile_name.close()
    ofile_name.close()

谢谢

更新

这是输入文件的样子:

The first line never changes. 
The second line was a bit much longer. 
The third line was short. 
The fourth line was nearly the longer line. 
The fifth was tiny. 
The sixth line is just one line more.
The seventh line was the last line of the original file.

当代码正确时,输出文件应如下所示

The first never changes. 
The second was a bit much. 
The third was short. 
The fourth was the. 
The fifth was tiny. 
The sixth is just one more.
The seventh was the of the.

【问题讨论】:

  • 你需要分割空格,然后使用正则表达式将字母与单词匹配,如果是大小写则替换为空字符串
  • 它不起作用,因为您将 l 替换为空。这意味着您的 delete_list 变为空。您需要将替换与您的 ifile_name 一起使用,而不是与 delete_list 一起使用。因此,您的 ifile_name 写为空。
  • 文件有多大?能完全融入记忆吗?
  • @RNar 要删除的单词包含字母'L' 小写'l' 看起来像大写'i'
  • 它带有字母“l”的单词与“L”的小版本一样。你可能把它误认为是字母“i”? :)

标签: python file input output


【解决方案1】:

好好想想,你在循环什么?

for line in ifile_name: #line == every line in the file
    for word in delete_list: #word is equal to every 'word' (although it is mroe a letter) in delete_list
        line = line.replace(word, "") #you are replacing word (which is 'l') with a space

你可能想要更多类似的东西:

for line in ifile_name:
        for word in line.split(): #iterate through words in your line, not delete_list
            if any(x in word for x in delete_list): #check if any of the letters in delete_list are in word
                line = line.replace(word,'') #replace the whole word with blanks

请注意,使用此代码,您会留下额外的空格:

this_line_is -> this__is
    ^    ^          ^^

因此您可以致电:line = line.replace(word+' ', ''),但这可能会导致'wordwithl.' 等案例出现问题

【讨论】:

    【解决方案2】:

    没有看到你的文件是什么样的,很难说出确切使用什么,所以如果你能更新问题,那就太好了

    但目前您正在遍历每个字母而不是单词...使用 split() 将单词拆分为一个列表并更改该列表,然后将单词重新连接在一起以获得一个没有包含您的字母的单词的字符串

    words = ''
    with open(ifile_name,"r") as file:
        for line in file:
            list_of_words = line.split(' ')
            for key, word in enumerate(list_of_words):
                if 'l' in word:
                    list_of_words[key] = ''
    
            words += ' '.join(w for w in list_of_words if w != '')
            words += '\n'
    
    with open(ofile_name, "w+") as file:
        file.write(words)
    

    这样做的好处是您对空白没有任何问题。你会得到一个带有单个空格的常规字符串

    编辑:正如 cmets 中所指出的,一种更好的方法(整个文件不在内存中)是内联

    with open(ifile_name,"r") as in_file, open(ofile_name, "w+") as out_file:
        for line in file:
            list_of_words = line.split(' ')
            for key, word in enumerate(list_of_words):
                if 'l' in word:
                    list_of_words[key] = ''
    
            out_file.write(' '.join(w for w in list_of_words if w != ''))
    

    【讨论】:

    • 嗨,约翰,我已经更新了问题。对此深表歉意。
    • 嗨@colin!不用担心,我更新了我的答案。它应该是一个可行的解决方案,并且很容易理解正在发生的事情。但是如果您对此有任何疑问,请随时提出,我可以解释:)
    • 谢谢约翰,非常感谢您的帮助。另外,感谢您指出这个问题,我对堆栈溢出和python都很陌生。有像你这样的人在需要时得到建议和帮助真是太好了,尤其是课外时间。谢谢约翰。
    • @colin 确定!如果您有更多问题可以问我,我很乐意提供帮助:) 如果此答案解决了您的问题,请不要忘记用选票旁边的复选标记将其标记为已接受!这样可以认为问题已解决:)
    • 值得指出这可能会在内存中存储大量数据并从列表中删除是O(n) 操作,在您编写时根本不需要将数据存储在内存中数据到另一个文件,更重要的是,这也会从您的列表中删除错误的单词。你永远不应该改变你正在迭代的列表
    【解决方案3】:

    如果您只想要一个完整的新文件而不保留删除单词的记录,那么这是一个非常简单的解决方案,不需要您将所有数据存储在内存中:

    def remove_words(in_file, to_remove, out_file):
        with open(in_file) as f, open(out_file, "w") as f2:
            f2.writelines(" ".join([word for word in line.split()
                             if not to_remove.issubset(word)]) + "\n"
                                 for line in f)
    
    
    remove_words("test.txt", {"l"}, "removed.txt")
    

    所以现在删除包含您更新的行:

    In [23]: cat test.txt
    The first line never changes.
    The second line was a bit much longer.
    The third line was short.
    The fourth line was nearly the longer line.
    The fifth was tiny.
    The sixth line is just one line more.
    The seventh line was the last line of the original file.
    
    In [24]: remove_words("test.txt",{"l"},"removed.txt")
    
    In [25]: cat removed.txt
    The first never changes.
    The second was a bit much
    The third was short.
    The fourth was the
    The fifth was tiny.
    The sixth is just one more.
    The seventh was the of the
    

    【讨论】:

    • { 不是字典的文字符号吗? {"1", "2"} 是无效语法吗?我可能弄错了,我并不是想变得粗鲁或任何事情,只是想,因为您在评论中说 set 您想要一个通常用括号表示的集合..您可以指定 set('i', 'j')。这是一个新的 python 3 东西吗?
    • @JohnRuddell,不,这取决于你如何使用它 {K:V} 是一个字典文字,{a,b} 是一个集合文字
    • 哦,好吧,那我很抱歉。每天都学新东西:)
    【解决方案4】:

    一个想法可能是使用regular expressionre.sub(r'\S*l\S*',r'',text),然后完整的程序如下:

    import re
    
    def my_main(ifile_name, ofile_name):
        with open (ifile_name,"r") as ifile_name :
            text=ifile_name.read()
        text2 = re.sub(r'\S*l\S*',r'',text)
        with open(ofile_name, "w+") as ofile_name :
            ofile_name.write(text2)
    

    一个问题是只有单词本身会被删除,而不是它周围的空格。一个潜在的解决方案是在单词旁边(或之前)也捕获空间:

    re.sub(r'\S*l\S*\s*',r'',text)
    

    读取的程序:

    import re
    
    def my_main(ifile_name, ofile_name):
        with open (ifile_name,"r") as ifile_name :
            text=ifile_name.read()
        text2 = re.sub(r'\S*l\S*\s*',r'',text)
        with open(ofile_name, "w+") as ofile_name :
            ofile_name.write(text2)
    

    这种方法的一个潜在缺点是文件需要适应(虚拟)内存:对于大文件(1 GiB+),进程可能会因为使用过多资源而减慢甚至被操作系统杀死。

    【讨论】:

      猜你喜欢
      • 2011-06-13
      • 1970-01-01
      • 2017-04-28
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-14
      相关资源
      最近更新 更多