0

我正在尝试从文件中的多行创建字典,例如

grocery store
apples
banana
bread

shopping mall
movies
clothing stores
shoe stores

我要做的是让每个部分(即杂货店和购物中心)的第一行成为键和下面的所有东西(分别是苹果、香蕉、面包和电影、服装店、鞋店)的值。我一直在摆弄 readline 方法 + while 循环,但我无法弄清楚。如果有人知道,请帮忙。谢谢。

4

3 回答 3

1

@minopret 已经给出了一个对教学有用的答案,并且对于初学者来说很重要。从某种意义上说,甚至一些看起来更复杂的方法也经常在幕后做这件事——我的意思是使用一种状态机——所以了解这一点很重要。

但是为了它,我将描述一个更高级别的方法。有一个方便的功能itertools.groupby可以将序列分组为连续的组。在这种情况下,我们可以通过一堆不全为空的行来定义一个组——bool(line)如果False该行为空,True否则,然后dict从它们构建一个。

from itertools import groupby

with open("shopdict.txt") as fin:
    stripped = map(str.strip, fin)
    grouped = (list(g) for k,g in groupby(stripped, bool) if k)
    d = {g[0]: g[1:] for g in grouped}
于 2013-03-18T04:04:08.737 回答
1

一种解决方案是将布尔值存储在一个变量中,以确定您是否在一个部分的开头。我不想放弃令人兴奋的(?)结局,但你可以从is_first=True.

好吧,我想我还是想放弃结局。这就是我的想法,或多或少:

with open(fname) as f:
    content = f.readlines()

is_first = True
d = {}

for line in content:
    if line == '\n':
        is_first = True
    elif is_first:
        key = line
        is_first = False
    else:
        if key not in d:
            d.put(key, '')
        d.put(key, d.get(key) + line)
        is_first = False

我发现以这种方式规划代码更容易。当然,你也可以在没有is_first变量的情况下解决这个问题,特别是如果你已经完成了使用is_first变量的练习。我认为以下是正确的,但我并没有非常小心:

with open(fname) as f:
    content = f.readlines()

d = {}

while content:
    key, content = content[0], content[1:]
    if key != '\n':
        value, content = content[0], content[1:]
        while value != '\n':
            if key not in d:
                d.put(key, '')
            d.put(key, d.get(key) + value)
            value, content = content[0], content[1:]
于 2013-03-18T01:28:38.547 回答
0
from itertools import groupby
with open("shopdict.txt") as fin:
    stripped = map(str.strip, fin)
    d = {k: g for b, (k, *g) in  groupby(stripped, bool) if b}

这是一种只使用for循环的方法

d={}
with open("shopdict.txt") as fin:
    for key in fin:
        key = key.strip()
        d[key] = []
        for item in fin:
            if item.isspace():
                break
            d[key].append(item.strip())
于 2013-03-18T10:33:28.780 回答