Python从配置创建字典的字典
作为内部项目的一部分,我必须解析dns区域文件记录。该文件大致如下所示Python从配置创建字典的字典,python,dictionary,data-structures,Python,Dictionary,Data Structures,作为内部项目的一部分,我必须解析dns区域文件记录。该文件大致如下所示 $ORIGIN 0001.test.domain.com. test-qa CNAME test-qa.0001.test.domain.com. $ORIGIN test-qa.domain.com. unit-test01 A 192.168.0.2 $TTL 60 ; 1 minute integration-test A 192.168
$ORIGIN 0001.test.domain.com.
test-qa CNAME test-qa.0001.test.domain.com.
$ORIGIN test-qa.domain.com.
unit-test01 A 192.168.0.2
$TTL 60 ; 1 minute
integration-test A 192.168.0.102
$ORIGIN dev.domain.com.
web A 192.168.10.10
$TTL 300; 5 minutes
api A 192.168.10.13
默认ttl为3600,即对于上述数据
test-qa CNAME test-qa.0001.test.domain.com.
它的ttl为3600,因为在任何地方都没有提到$ttl。但是,
unit-test01 A 192.168.0.2
具有3600的ttl和
integration-test A 192.168.0.102
具有60秒的ttl
我正试图用上面的数据创建一个数据结构,我想字典可能是遍历这些数据的最佳方式
我所做的:
origin = re.compile("^\$ORIGIN.*")
ttl = re.compile("^$TTL.*")
default_ttl = "$TTL 3600"
data_dict = {}
primary_key = None
value = None
for line in data_zones:
if origin.search(line):
line = line.replace("$ORIGIN ", "")
primary_key = line
elif ttl.search(line):
default_ttl = line
else:
value = line
data_dict[primary_key] = [default_ttl]
data_dict[primary_key][default_ttl] = value
我想把它转换成字典,但我得到了错误
TypeError: list indices must be integers, not str
我的示例数据结构需要如下所示
0001.test.domain.com.: #This would be the first level Key
ttl:3600: #This would be the second level key
test-qa CNAME test-qa.0001.test.domain.com. #Value
test-qa.domain.com.: #This would be the first level Key
ttl:3600: #This would be the second level key
unit-test01 A 192.168.0.2 #value
ttl:60: #This would be the second level key
integration-test A 192.168.0.102 #value
我在这里做错了什么?在我们研究问题的细节之前,在这段代码中有一些东西可以被清除,从而使错误更容易被发现。遵循代码质量准则可以使代码更易于维护和理解,特别是变量名应该始终是描述性的,并告诉读者变量将代表什么。一个坏的变量名不会告诉读者它包含什么,一个糟糕的变量名会告诉读者这个变量包含它不包含的东西 这里有一个名为default\u ttl的变量。一个偶然的读者可能会假设这个变量总是包含默认的ttl,但是在上面的代码示例中,一旦在源数据中指定了ttl,这个变量就会被覆盖
default_ttl = line
如果在代码顶部指定一个默认TTL,然后在遇到新原点时使用将该值赋给一个名为current_TTL的变量,可能会更清楚
因此,在文件的顶部,我们将有:
DEFAULT_TTL = '$TTL 3600'
每次遇到新原点时,当前ttl都会重置为默认值
if origin.search(line):
line = line.replace("$ORIGIN ", "")
current_ttl = DEFAULT_TTL
当源数据中遇到特定的TTL时,可以为当前TTL分配适当的值:
elif ttl.search(line):
current_ttl = line
一旦进行此更改,代码的最后两行将变为:
data_dict[primary_key] = [current_ttl]
data_dict[primary_key][current_ttl] = value
错误的原因是您正在创建一个只包含一个条目的列表-当前的\u ttl,并在包含该列表的数据字典中创建一个条目
在下一行,您从字典中获取列表,并尝试使用索引current\u ttl访问它。当前ttl包含一个字符串,只能使用整数访问列表。解释器会给你一条错误消息,简洁地总结了这一点
在不对代码进行重大修改的情况下,最快的清理方法是对顶级数据使用defaultdict:
from collections import defaultdict
data_dict = defaultdict(dict)
现在,每当我们试图引用data_dict中不存在的键时,defaultdict对象将为我们创建一个新的空字典,并在我们试图访问的键处插入data_dict
线路
data_dict[primary_key] = [default_ttl]
现在是多余和不必要的,可以从代码中完全删除它,留下:
from collections import defaultdict
origin = re.compile("^\$ORIGIN.*")
ttl = re.compile("^$TTL.*")
DEFAULT_TTL = "$TTL 3600"
data_dict = defaultdict(dict)
primary_key = None
value = None
for line in data_zones.split('\n'): #Split by line not character
if origin.search(line):
line = line.replace("$ORIGIN ", "")
current_ttl = DEFAULT_TTL
primary_key = line
elif ttl.search(line):
current_ttl = line
else:
value = line
data_dict[primary_key][current_ttl] = value
误差线是
data_dict[primary_key][default_ttl] = value
因为data\u dict[primary\u key]
是一个列表而不是字典对象。您可以通过执行以下操作来解决此问题
data_dict[primary_key] = {default_ttl: value}