我有一个文本文件,我想将它加载到Python中的字典中。
文本看起来像这样,制表符分隔:
Form Dosage ReferenceDrug drugname activeingred 注射用;注射20,000单位/ ML LIQUAEMIN SODIUM HEPARIN SODIUM 注射用;注射40,000单位/ ML LIQUAEMIN SODIUM HEPARIN SODIUM 注射用;注射5,000单位/ ML LIQUAEMIN SODIUM HEPARIN SODIUM
现在我的代码看起来像这样,但它不起作用(列表索引超出范围,没有任何东西被推送到字典)。我不知道我哪里出错了,不知道程序员。谢谢你的帮助。
import sys
def load_medications(filename):
meds_dict = {}
f = open(filename)
l = " "
# print f.read()
for line in f:
fields = l.split("\t")
ApplNo = fields[0]
ProductNo = fields[1]
Form = fields[2]
Dosage = fields[3]
ProductMktStatus = fields[4]
TECode = fields[5]
ReferenceDrug = fields[6]
DrugName = fields[7]
ActiveIngred = fields[8]
meds = {
"ApplNo": ApplNo,
"ProductNo": ProductNo,
"Form": Form,
"Dosage": Dosage,
"ProductMktStatus": ProductMktStatus,
"TECode": TECode,
"ReferenceDrug": ReferenceDrug,
"DrugName": DrugName,
"ActiveIngred": ActiveIngred
}
meds_dict[DrugName] = meds
f.close()
return meds_dict
def main():
x = load_medications("druglist.txt")
print x
if __name__ == "__main__":
main()
答案 0 :(得分:2)
试试line.split
而不是l.split
?
答案 1 :(得分:2)
您可以更轻松地使用the CSV module in the standard library解析此数据 - 如果您使用制表符作为分隔符并将;
作为行终止符进行装配,则解析您发布的文件时应该没有任何问题
使用DictReader也可以让您更轻松地阅读行(您可以将内容称为line['ApplNo']
而不是line[0]
)。
不幸的是,它看起来不像你文件中的标题映射到你想在代码中调用它们的那些 - 所以你需要根据字典中的内容自己分配字段的名称。
答案 2 :(得分:1)
您应该查看csv.DictReader
,假设您的文件在开头有一个正确的标题行,您应该可以像这样简单地创建您的词典:
def load_medications(filename):
reader = csv.DictReader(open(filename), delimiter='\t')
meds = {}
for row in reader:
meds[row['DrugName']] = row
return meds
如果您的文件没有标题行,则可以将字段名称传递给DictReader
初始化程序:
fields = ["ApplNo", "ProductNo", "Form", "Dosage", "ProductMktStatus"
"TECode", "ReferenceDrug", "DrugName", "ActiveIngred"]
reader = csv.DictReader(open(filename), delimiter='\t', fieldnames=fields)
答案 3 :(得分:0)
我认为你高估了文件的列数。 ApplNo
,ProductNo
在哪里?
答案 4 :(得分:0)
您实际上拆分了l
,而不是line
。你想要:
def load_medications(filename):
meds_dict = {}
with open(filename) as f: # Ensure that the file gets closed
for line in f:
fields = line.split("\t") # line, not l
keys = ["ApplNo", "ProductNo", "Form", "Dosage", "ProductMktStatus",
"TECode", "ReferenceDrug", "DrugName", "ActiveIngred",]
if len(fields) != len(keys):
raise ValueError("Malformed input line " + repr(line))
meds = dict(zip(keys, fields))
meds_dict[meds["DrugName"]] = meds
return meds_dict
答案 5 :(得分:0)
看起来您的代码假定特定药物有9种属性。您发布的示例文本文件只有5个属性。当您调用fields = l.split("\t")
时,将返回仅包含5个元素的数组,因为“druglist.txt”中只有5个元素。因此,如果您使用大于或等于5的值(即fields
)索引fields[8]
,您将获得“索引超出范围”异常。
答案 6 :(得分:0)
由于您的字段名称都是有效的Python标识符,为什么不将您的数据读入namedtuples而不是dicts?
data = """Form Dosage ReferenceDrug drugname activeingred INJECTABLE; INJECTION 20,000 UNITS/ML LIQUAEMIN SODIUM HEPARIN SODIUM INJECTABLE; INJECTION 40,000 UNITS/ML LIQUAEMIN SODIUM HEPARIN SODIUM INJECTABLE; INJECTION 5,000 UNITS/ML LIQUAEMIN SODIUM HEPARIN SODIUM INJECTABLE""".split('; ')
from collections import namedtuple
# define class DrugData as a namedtuple, using the headers from data[0]
DrugData = namedtuple("DrugData", data[0])
# use a list comprehension to create a DrugData for each data line
druglist = [DrugData(*line.split('\t')) for line in data[1:]]
# access each tuple in druglist, using attribute access to individual fields
for d in druglist:
print "%s | %s | %s" % (d.ReferenceDrug, d.Form, d.Dosage)
打印:
LIQUAEMIN | INJECTION | 20,000 UNITS/ML
LIQUAEMIN | INJECTION | 40,000 UNITS/ML
LIQUAEMIN | INJECTION | 5,000 UNITS/ML
编辑:
回顾原始问题,看起来您想要创建所有这些条目的单个字典,由drugname
键入。不幸的是,dict键必须是唯一的,在您的示例中,所有3个条目都具有相同的drugname
。您可能必须组合2个或更多字段才能为处理所有这些值的字典组成一个真正唯一的键,例如(drugname, Dosage)
的元组。
或者,稍微更改您的设计,以便每个drugname
指向匹配值的列表。最简单的方法是使用defaultdict而不是dict,以便使用空列表自动初始化新条目。在您的代码中,您将添加一个import语句:
from collections import defaultdict
并将meds_dict的声明更改为:
meds_dict = defaultdict(list)
意味着任何尚未见过的新密钥都将使用作为defaultdict参数提供的函数/类进行初始化,在本例中为list
。
然后要向meds_dict添加新条目,而不是使用'='分配,您将附加到所有匹配的meds /剂量列表中:
meds_dict[DrugName].append(meds)
现在对于任何DrugName,您将获得匹配表格/剂量/等的列表。记录。