Python 从配置创建字典的字典
Python creating dictionary of dictionary from a configuration
作为内部项目的一部分,我必须解析一个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.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
的 ttl 为 3600 并且
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
我做错了什么?
在我们查看问题的详细信息之前,可以清理此代码中的一些内容,以便更容易找到错误。遵循代码质量准则可以使代码更易于维护和理解,尤其是 - 变量名称应始终具有描述性,并告诉 reader 变量将代表什么。一个糟糕的变量名不会告诉 reader 它包含什么,而一个糟糕的变量名会告诉 reader 该变量包含它不包含的东西。
这里我们有一个变量叫做default_ttl。随意 reader 可能会假设此变量始终包含默认的 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
错误的原因是您正在创建一个只包含一个条目的列表 - current_ttl,并在包含该列表的 data_dict 字典中创建一个条目。
在下一行,您从字典中取回列表,并尝试使用索引 current_ttl 访问它。 current_ttl 包含字符串,列表只能使用整数访问。解释器给你一条错误信息,简明扼要地总结了这一点!
在不对代码进行重大修改的情况下,最快的清理方法是对顶层使用 defaultdict data_dict:
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_dict[primary_key]
是一个列表而不是字典对象。你可以通过
来解决这个问题
data_dict[primary_key] = {default_ttl: value}
作为内部项目的一部分,我必须解析一个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.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
的 ttl 为 3600 并且
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
我做错了什么?
在我们查看问题的详细信息之前,可以清理此代码中的一些内容,以便更容易找到错误。遵循代码质量准则可以使代码更易于维护和理解,尤其是 - 变量名称应始终具有描述性,并告诉 reader 变量将代表什么。一个糟糕的变量名不会告诉 reader 它包含什么,而一个糟糕的变量名会告诉 reader 该变量包含它不包含的东西。
这里我们有一个变量叫做default_ttl。随意 reader 可能会假设此变量始终包含默认的 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
错误的原因是您正在创建一个只包含一个条目的列表 - current_ttl,并在包含该列表的 data_dict 字典中创建一个条目。
在下一行,您从字典中取回列表,并尝试使用索引 current_ttl 访问它。 current_ttl 包含字符串,列表只能使用整数访问。解释器给你一条错误信息,简明扼要地总结了这一点!
在不对代码进行重大修改的情况下,最快的清理方法是对顶层使用 defaultdict data_dict:
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_dict[primary_key]
是一个列表而不是字典对象。你可以通过
data_dict[primary_key] = {default_ttl: value}