【问题标题】:Problems using readline method with nested while loops Python使用带有嵌套while循环Python的readline方法的问题
【发布时间】:2014-12-14 22:07:00
【问题描述】:

我正在尝试编写一个代码,该代码将采用包含单词及其定义的 .txt 文件并生成 {'word1':['definition1', 'definition2'...]} 的字典。 .txt 文件格式如下:

单词1

定义1

定义2

(空行)

word2

定义1

定义2 ...

到目前为止,我编写的函数体如下:

line = definition_file.readline()
dictx = {}

while line != '':
    key = line.strip()
    defs = []
    line = definition_file.readline()
    while line != '\n':
        defx = [line.strip()]
        defs += defx
        line = definition_file.readline()
    if key not in dictx:
    dictx[key] = defs

return dictx

我很快意识到这段代码的问题是它只会返回一个包含第一个单词的字典。我需要一种使代码循环的方法,以便它返回一个包含所有单词+定义的字典。我希望做到这一点不使用休息

谢谢!

【问题讨论】:

    标签: python dictionary while-loop readline


    【解决方案1】:

    应该这样做:

    from collections import defaultdict
    
    d = defaultdict(list)
    is_definition = False
    
    with open('test.txt') as f:
        for line in f:
            line = line.strip().rstrip('\n')
            if line == '':                     # blank line
                is_definition=False
                continue
            if is_definition:                  # definition line
                d[word].append(line)
            else:                              # word line
                word = line
                is_definition = True
    

    【讨论】:

      【解决方案2】:

      这种单线也可以解决问题:

      >>> tesaurus = open('tesaurus.txt').read()
      >>> dict(map(lambda x: (x[0], x[1].split()), [term.split("\n", 1) for term in tesaurus.replace("\r", "").split("\n\n")]))
      {'word1': ['definition1', 'definition2'], 'word3': ['def1', 'def2'], 'word2': ['definition1', 'definition2']}
      

      【讨论】:

        【解决方案3】:

        这是另一种可能性:

        d = dict()
        defs = list()
        with open('test.txt') as infile:
           for line in infile:
               if not line:
                    d[defs[0]] = defs[1:]
                    defs = list()
               else:
                    defs.append(line.strip())
        

        【讨论】:

          【解决方案4】:

          读取整个文件

          d = dict()
          with open('file.txt') as f:
              stuff = f.read()
          

          在空行上拆分文件。

          word_defs = stuff.split('\n\n')
          

          遍历定义组并从定义中拆分单词。

          for word_def in word_defs:
              word_def = word_def.split('\n')
              word = word_def[0]
              defs = word_def[1:]
              d[word] = defs
          

          如果您更喜欢功能性 /compact(相同但不同)。首先是生成[word, def, def, ...] 组的迭代器。

          definition_groups = (thing.split('\n') for thing in stuff.split('\n\n'))
          

          字典理解来构建字典

          import operator
          word = operator.itemgetter(0)
          defs = operator.itemgetter(slice(1,None))
          g = {word(group):defs(group) for group in definition_groups}
          

          【讨论】:

            【解决方案5】:

            这是我符合您标准的最佳答案。

            import sys
            
            d = {}
            with open(sys.argv[1], "r") as f:
                done = False
                while not done:
                    word = f.readline().strip()
                    done = not word
            
                    line = True
                    defs = []
                    while line:
                        line = f.readline().rstrip('\n')
                        if line.strip():
                            defs.append(line)
                    if not done:
                        d[word] = defs
            print(d)
            

            但我不明白您为什么要避免使用break。我认为这段代码使用break 更清晰...控制流程更简单,我们不需要那么多变量。当word 是一个空字符串时,这段代码就会中断(立即停止它正在做的事情),这很容易理解。您必须研究第一个代码,以确保您知道到达文件结尾时它是如何工作的。

            import sys
            
            d = {}
            with open(sys.argv[1], "r") as f:
                while True:
                    word = f.readline().strip()
                    defs = []
                    if not word:
                        break
            
                    while True:
                        line = f.readline().rstrip('\n')
                        if not line:
                            break
                        defs.append(line)
                    d[word] = defs
            print(d)
            

            但我认为最好的编写方法是创建一个辅助函数,将解析定义的工作打包:

            import sys
            
            def _read_defs(f):
                while True:
                    line = f.readline().rstrip('\n')
                    if not line:
                        break
                    yield line
            
            d = {}
            with open(sys.argv[1], "r") as f:
                while True:
                    word = f.readline().strip()
                    if not word:
                        break
                    d[word] = list(_read_defs(f))
            print(d)
            

            第一个比较棘手,因为它避免使用break。其他的更容易理解,两个相似的循环具有相似的控制流。

            【讨论】:

              猜你喜欢
              • 2021-07-31
              • 1970-01-01
              • 2021-08-21
              • 2016-06-06
              • 2015-07-04
              • 1970-01-01
              • 2017-08-15
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多