【问题标题】:How do I write a function that returns true if there are duplicate words in a file [closed]如果文件中有重复的单词,我如何编写一个返回true的函数[关闭]
【发布时间】:2014-01-29 22:21:17
【问题描述】:

这是函数

def duplicate(fname):
    'returns true if there are duplicates in the file, false otherwise'
    fn = open(fname, 'r')
    llst = fn.readlines()
    fn.close()

我不知道该怎么做。我尝试拆分文件,对其进行排序,然后编写一个函数来查找两个相同的单词是否按连续顺序排列。但它说我不能将拆分归因于列表。

有什么想法吗?

【问题讨论】:

  • 请更清楚地说明您的规范 - 一个应该 return True 和一个应该 return False 的输入示例会很有用。
  • 抱歉,我会注意的

标签: python string file duplicates


【解决方案1】:

您可以将每个单词作为键添加到字典中。如果密钥已经存在,则它是重复的。您还可以将找到单词的次数的计数关联为值。

#!/usr/bin/env python
def duplicate(fname):
    'returns true if there are duplicates in the file, false otherwise'
    with open (fname, 'r') as file_handle:
        word_dict = dict()
        for line in file_handle:
            words = line.split()
            for word in words:
                if word in word_dict:
                    word_dict[word] = 'Duplicate'
                else:
                    word_dict[word] = 'Unique'
    return word_dict

results = duplicate('alice.txt')
for key in results:
    print "{}: {}".format(key, results[key])

【讨论】:

    【解决方案2】:

    您可以为此使用set 数据结构:

    def has_duplicate_words(filename):
        with open(filename, 'r') as f:
            words = set()
            for line in f.readlines():
                lineWords = line.split()
                for word in lineWords:
                    if word in words:
                        return True
    
                    words.add(word)
        return False
    

    还请注意,这取决于您对单词 的定义。在此解决方案中,它是不包含空白字符的任何字符序列,即split() 函数documentation 中定义的空格、制表符、换行符、回车符、换页符。

    如果您想返回所有重复项,您可以将它们累积在 list 中,而不是在找到重复项时执行 return True

    另请注意,如果文件可能包含无法放入内存的超长行,则此解决方案不可行。

    【讨论】:

    • 谢谢!但是我还是不明白 set 是怎么工作的。
    【解决方案3】:

    你在找这个吗?

    def duplicate(fname):
        with open(fname, "r") as f: # it's better to use with open, than only open, since otherwise the file might not be closed on error
            dict = {} # create an empty dictionary for checking, if a line was already in the file
            for line in f: # go through all lines
                try:
                    foo = dict[line] # check, if line already exists
                    return True # no error was thrown, so this is a duplicated line
                except:
                    dict[line] = 1 # give the key line some random input, so that the dict contains this key
        return False
    

    另一种方法是读入这个文件,对行进行排序,然后检查是否有重复的行,然后它们会相互跟随。

    请注意,如果文件包含行“foo”和“foo”,则由于第二行末尾的空格,这将不会返回 true 而是 false。

    【讨论】:

    • dict 在这里没有意义。你应该改用set
    • 好吧,在 python 中,字典和集合一样快,为什么不呢?
    • 好吧,你也可以自己实现一个dict,使其与内置一样快。您还可以在这里想到其他 10 个同样“快速”(无论您是什么意思)的解决方案。但是为了什么?为工作使用正确的工具。 dict 这里使代码不可读,将一些“随机输入”放入 dict 是没有意义的,并且会使读者感到困惑(因此需要代码中的 cmets)。 set 是这里最干净、最简单的解决方案。
    • 不,在 python 中自我实现的 dict 永远不会像在 dicts 中构建一样快。 Pythons dicts 是用 C++ 自己编写(和优化)的,所以只要你不导入 C++ 代码,它们总是更快。
    • 它实际上是 C(至少在最流行的 Python 实现中),当然为什么不自己编写它。无论如何,很高兴你试图解决我评论中最不相关的部分。想参考其余部分吗?
    【解决方案4】:

    更简单的方法:将文件中单词列表的长度与一组单词的长度进行比较:

    >>> def HasDuplicates(str):
    ...    words = str.split()
    ...    uniqueWords = set(words)
    ...    return len(words) != len(uniqueWords)
    ...
    >>> str1 = "this is a sentence with two two duplicates"
    >>> str2 = "this is a sentence with no duplicates"
    >>> HasDuplicates(str1)
    True
    >>> HasDuplicates(str2)
    False
    

    (文件 I/O 留给读者作为练习;它与是否重复的问题并不密切相关)

    【讨论】:

      【解决方案5】:

      这行得通:

      如果有重复,它会返回True,但还会构建一个字典,其中重复的单词为key,它们在文本中的频率为value,并打印出来。我知道的比您要求的要多,但是更改代码以检查重复项并返回 True/False 并不需要太多。

      def duplicate(fname):
      
          with open(fname, 'r') as f:
              text = f.read() # auto closes file after reading
      
          split_text = [word.strip() for word in text.split()] # create list of all the words
      
          duplicates = {}
          for word in split_text:
              count = text.count(word) # count occurrences of each word
              if count > 1:
                  duplicates[word] = count
          if duplicates:
              print duplicates
              return True
          return False
      

      示例输出:

      {'dear': 2, 'the': 6, 'name': 2}
      

      【讨论】:

        【解决方案6】:
        with open('filepath','r') as f:
            all_words = f.read().split()
            return len(all_words) > len(set(all_words))
        

        【讨论】:

        • 你为什么在那里使用列表理解? split() 的返回值已经与您在理解中创建的列表完全相同...
        • 你是对的!那是我尝试的不同算法的剩余部分。谢谢!
        猜你喜欢
        • 2020-01-08
        • 2023-01-05
        • 2022-01-12
        • 2021-03-15
        • 1970-01-01
        • 2017-04-10
        • 2021-04-20
        • 2021-02-03
        • 2017-01-31
        相关资源
        最近更新 更多