Python:从一个文件中读取多行,并使实例存储在字典中
Python: Read multiple lines from a file and make instances stored in an dictionary
我的奋斗:
阅读两行并跳过第三行。
然后我想将所有对象存储在字典中,名称作为键。
**** Ingredients.txt ****
Name1
ingredient1/ingredient2/ingredient3
Name2
ingredient1/ingredient2
Name3
...
class Foodset(object):
def __init__(self, name):
self.name = name
self.ingredients = set([])
def __str__(self):
return str(self.name) + ' consits of: ' + ", ".join(str(e) for e in self.ingredients) + '.'
def setIngredients(self, list):
for i in list:
self.ingredients.add(i)
def getMenu(file="ingredients.txt"):
with open(file, 'r') as indata:
menu = dict()
for line in indata:
tempString = str(line.rstrip('\n'))
menu[tempString] = Foodset(tempString)
我想阅读下一行并将其存储为配料,然后跳过第三行,因为它是空白的。然后重复。
我在 for 循环中遇到的问题是我不能在同一个循环中存储两个不同的行,然后引用同一个对象以使用 setIngredients() 方法。 还有哪些其他方法可以在每个循环中读取多行?
编辑:
@Arpan 想出了一个快速解决方案,使用 indata.readlines() 列出每行并以 3 步循环,同时存储第一个和第二个值并跳过第三个值。
我刚刚想出了另一个解决方案,在 while 循环中使用 readline() 方法 3 次。使用 readline() 是我最初想要的。
def getMenu(menu="ingredients.txt"):
with open(menu, "r") as indata:
menu = dict()
while True:
name = indata.readline().strip('\n')
ingredientList = indata.readline().strip().split('/')
if name == "":
break
# here I just added a parameter that directly set the attribute "ingredients" inside the object.
menu[name] = Foodset(name, ingredientList)
indata.readline()
return menu
由于这不是代码编写服务,我将向您展示一种解析文件的方法。根据菜肴及其配料建立字典是简单的部分,所以我会把它留给你。
演示文件input.txt:
Name1
ingredient1/ingredient2/ingredient3
Name2
ingredient1/ingredient2
Name3
ingredient1/ingredient2/ingredient3
代码:
from itertools import izip_longest
with open('input.txt') as infile:
for name, ingr, _ in izip_longest(*[infile]*3, fillvalue='\n'):
ingredients = ingr.split('/')
print name.strip()
for ing in ingredients:
print ing.strip()
print
输出:
Name1
ingredient1
ingredient2
ingredient3
Name2
ingredient1
ingredient2
Name3
ingredient1
ingredient2
ingredient3
解释:
infile
是一个迭代器,传了3次给izip_longest
,所以每次迭代izip_longest
都会对同一个迭代器调用3次next
。我使用空行作为 fillvalue
参数,以防您的文件不以空行结尾。
用 '/'
字符拆分包含配料的字符串将为您提供配料列表。
还有更多 explanation/information 以及一些关于如何一次从文件中读取多行的替代方法 here。
尝试这样的事情。
with open(file, 'r') as indata:
lines = indata.readlines()
menu = dict()
for i in xrange(0, len(lines), 3):
name = lines[i].rstrip('\n')
ingredients = lines[i+1].rstrip('\n').split('/')
f = Foodset(name)
f.setIngredients(ingredients)
menu[name] = f
对于 python 3.x 使用 range
而不是 xrange
。
您可以使用 itertools.islice
一次阅读三行
import itertools
with open('ingredients.txt') as f:
while True:
next_three_lines = list(itertools.islice(f, 3))
if not next_three_lines:
break
else:
print next_three_lines
在你的情况下,这将打印
['Name1\n', 'ingredient1/ingredient2/ingredient3\n', '\n']
['Name2\n', 'ingredient1/ingredient2\n', '\n']
['Name3\n', '...']
然后您可以将打印行更改为 rstrip('\n')
并使用每个 next_three_lines
的前两个元素来构建您的对象:
tempString = str(next_three_lines[0].rstrip('\n'))
menu[tempString] = Foodset(tempString)
menu[tempString].setIngredients(next_three_lines[1].rstrip('\n').split('/')
我的奋斗:
阅读两行并跳过第三行。
然后我想将所有对象存储在字典中,名称作为键。
**** Ingredients.txt ****
Name1
ingredient1/ingredient2/ingredient3
Name2
ingredient1/ingredient2
Name3
...
class Foodset(object):
def __init__(self, name):
self.name = name
self.ingredients = set([])
def __str__(self):
return str(self.name) + ' consits of: ' + ", ".join(str(e) for e in self.ingredients) + '.'
def setIngredients(self, list):
for i in list:
self.ingredients.add(i)
def getMenu(file="ingredients.txt"):
with open(file, 'r') as indata:
menu = dict()
for line in indata:
tempString = str(line.rstrip('\n'))
menu[tempString] = Foodset(tempString)
我想阅读下一行并将其存储为配料,然后跳过第三行,因为它是空白的。然后重复。
我在 for 循环中遇到的问题是我不能在同一个循环中存储两个不同的行,然后引用同一个对象以使用 setIngredients() 方法。 还有哪些其他方法可以在每个循环中读取多行?
编辑: @Arpan 想出了一个快速解决方案,使用 indata.readlines() 列出每行并以 3 步循环,同时存储第一个和第二个值并跳过第三个值。
我刚刚想出了另一个解决方案,在 while 循环中使用 readline() 方法 3 次。使用 readline() 是我最初想要的。
def getMenu(menu="ingredients.txt"):
with open(menu, "r") as indata:
menu = dict()
while True:
name = indata.readline().strip('\n')
ingredientList = indata.readline().strip().split('/')
if name == "":
break
# here I just added a parameter that directly set the attribute "ingredients" inside the object.
menu[name] = Foodset(name, ingredientList)
indata.readline()
return menu
由于这不是代码编写服务,我将向您展示一种解析文件的方法。根据菜肴及其配料建立字典是简单的部分,所以我会把它留给你。
演示文件input.txt:
Name1
ingredient1/ingredient2/ingredient3
Name2
ingredient1/ingredient2
Name3
ingredient1/ingredient2/ingredient3
代码:
from itertools import izip_longest
with open('input.txt') as infile:
for name, ingr, _ in izip_longest(*[infile]*3, fillvalue='\n'):
ingredients = ingr.split('/')
print name.strip()
for ing in ingredients:
print ing.strip()
print
输出:
Name1
ingredient1
ingredient2
ingredient3
Name2
ingredient1
ingredient2
Name3
ingredient1
ingredient2
ingredient3
解释:
infile
是一个迭代器,传了3次给izip_longest
,所以每次迭代izip_longest
都会对同一个迭代器调用3次next
。我使用空行作为 fillvalue
参数,以防您的文件不以空行结尾。
用 '/'
字符拆分包含配料的字符串将为您提供配料列表。
还有更多 explanation/information 以及一些关于如何一次从文件中读取多行的替代方法 here。
尝试这样的事情。
with open(file, 'r') as indata:
lines = indata.readlines()
menu = dict()
for i in xrange(0, len(lines), 3):
name = lines[i].rstrip('\n')
ingredients = lines[i+1].rstrip('\n').split('/')
f = Foodset(name)
f.setIngredients(ingredients)
menu[name] = f
对于 python 3.x 使用 range
而不是 xrange
。
您可以使用 itertools.islice
一次阅读三行import itertools
with open('ingredients.txt') as f:
while True:
next_three_lines = list(itertools.islice(f, 3))
if not next_three_lines:
break
else:
print next_three_lines
在你的情况下,这将打印
['Name1\n', 'ingredient1/ingredient2/ingredient3\n', '\n']
['Name2\n', 'ingredient1/ingredient2\n', '\n']
['Name3\n', '...']
然后您可以将打印行更改为 rstrip('\n')
并使用每个 next_three_lines
的前两个元素来构建您的对象:
tempString = str(next_three_lines[0].rstrip('\n'))
menu[tempString] = Foodset(tempString)
menu[tempString].setIngredients(next_three_lines[1].rstrip('\n').split('/')