使用嵌套while循环Python的readline方法的问题

时间:2014-12-14 22:07:01

标签: python dictionary while-loop readline

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

WORD1

定义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

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

谢谢!

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

>>> 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']}

答案 2 :(得分:0)

这是另一种可能性:

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())

答案 3 :(得分:0)

阅读整个文件

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'))

dict comprehension来构建字典

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

答案 4 :(得分:0)

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

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。其他的更容易理解,有两个相似的循环具有相似的控制流。