从列表中删除包含单词的字符串,不重复字符串

时间:2013-12-20 15:21:20

标签: python duplicates

我正在尝试让我的代码从包含某些单词的文件中提取句子。我有下面的代码:

import re
f = open('RedCircle.txt', 'r')
text = ' '.join(f.readlines())
sentences = re.split(r' *[\.\?!][\'"\)\]]* *', text)

def finding(q):
    for item in sentences:
        if item.lower().find(q.lower()) != -1:
            list.append(item)

    for sentence in list:
        outfile.write(sentence+'\r\n')

finding('cats')
finding('apples')
finding('doggs')

但是如果句子是这样的话,这当然会给我(在outfile中)三次相同的句子:

'I saw doggs and cats eating apples' 

有没有办法轻松删除这些副本,或者制作代码以便文件中不会有任何重复项?

2 个答案:

答案 0 :(得分:2)

Python中几乎没有可以用来删除重复元素的选项(在这种情况下,我相信它的句子)。

  1. 使用Set
  2. 使用itertools.groupby
  3. OrderedDict作为OrderedSet,如果订单很重要
  4. 您需要做的就是将结果收集到一个列表中并使用此答案中提供的链接来创建您自己的配方以删除重复项。

    此外,不是在每次搜索到文件后转储结果,而是将其推迟到删除所有重复项。

    几点暗示性改变

    使用集

    1. 将您的功能转换为生成器

      def finding(q):
          return (item for item in sentences 
                  if item.lower().find(q.lower()) != -1)
      
    2. 链接每次搜索的结果

      from itertools import chain
      chain.from_iterable(finding(key) for key in ['cats', 'apples'. 'doggs'])
      
    3. 将结果传递给Set

      set(chain.from_iterable(finding(key) for key in ['cats', 'apples'. 'doggs']))
      
    4. 使用装饰器

      def uniq(fn):
          uniq_elems = set()
          def handler(*args, **kwargs):
              uniq_elems.update(fn(*args, **kwargs))
              return uniq_elems
          return handler
      @uniq
      def finding(q):
          return (item for item in sentences 
                  if item.lower().find(q.lower()) != -1)
      

      如果订单很重要

      将装饰器更改为使用OrderedDict

      def uniq(fn):
          uniq_elems = OrderedDict()
          def handler(*args, **kwargs):
              uniq_elems.update(uniq_elems.fromkeys(fn(*args, **kwargs)))
              return uniq_elems.keys()
          return handler
      

      注意

      • 避免命名与Python中的保留字冲突的变量(比如将变量命名为list

答案 1 :(得分:0)

首先,订单是否重要? 其次,如果它们实际上在原始文本文件中重复,是否应该出现重复项?

如果不是第一个,则是第二个: 如果你重写函数来获取一个搜索字符串列表并迭代它(这样它会检查你所追求的每个单词的当前句子),那么一旦找到它就可以突破循环。

如果是第一个是,是第二个, 在将项目添加到列表之前,请检查它是否已存在。具体来说,记下您在原始文本文件中传递的列表项,以及您将看到的下一个列表项。这样您就不必检查整个列表,只需检查一个项目。

如果你对第一个问题回答“否”而对第二个问题回答“是”,那么Abhijit建议的一组就会起作用。