我正在尝试从文件中的多行创建字典,例如
grocery store
apples
banana
bread
shopping mall
movies
clothing stores
shoe stores
我要做的是让每个部分(即杂货店和购物中心)的第一行成为键和下面的所有东西(分别是苹果、香蕉、面包和电影、服装店、鞋店)的值。我一直在摆弄 readline 方法 + while 循环,但我无法弄清楚。如果有人知道,请帮忙。谢谢。
我正在尝试从文件中的多行创建字典,例如
grocery store
apples
banana
bread
shopping mall
movies
clothing stores
shoe stores
我要做的是让每个部分(即杂货店和购物中心)的第一行成为键和下面的所有东西(分别是苹果、香蕉、面包和电影、服装店、鞋店)的值。我一直在摆弄 readline 方法 + while 循环,但我无法弄清楚。如果有人知道,请帮忙。谢谢。
@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}
一种解决方案是将布尔值存储在一个变量中,以确定您是否在一个部分的开头。我不想放弃令人兴奋的(?)结局,但你可以从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:]
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())