2017-06-01 47 views
1

我真的在努力编写代码对于这个问题:迭代通过嵌套上市来获取一个键值对

我的数据如下:

all_records = {u'ResourceRecordSets': [{u'Name': 'dev1.abc.com.', 
             u'ResourceRecords': [{u'Value': '10.0.3.214'}], 
             u'TTL': 300, 
             u'Type': 'A'}, 
             {u'Name': 'dev2.abc.com', 
             u'ResourceRecords': [{u'Value': '10.0.3.67'}], 
             u'TTL': 300, 
             u'Type': 'A'}]} 

我想通过这个名单来进行迭代当名称是dev1.abc.com

我不想定义一个新的函数,我只是想在for循环中执行此操作。

+4

其实你应该** **要定义一个新的功能 - 但无论如何,你可以更新你的问题,以显示你迄今为止编写的代码? – quamrana

+1

此外,如果您对代码进行格式化,则数据结构更加明显,这将有所帮助。 –

回答

2

末点尝试使用列表理解:

all_records = {u'ResourceRecordSets': [{u'Name': 'dev1.abc.com.', 
             u'ResourceRecords': [{u'Value': '10.0.3.214'}], 
             u'TTL': 300, 
             u'Type': 'A'}, 
             {u'Name': 'dev2.abc.com', 
             u'ResourceRecords': [{u'Value': '10.0.3.67'}], 
             u'TTL': 300, 
             u'Type': 'A'}]} 
value = [e['ResourceRecords'][0]['Value'] for e in all_records['ResourceRecordSets'] if e['Name']=="dev1.abc.com."] 
value 

value将是:

['10.0.3.214'] 
-1

如果你想使用高级功能:

  • 假设可能有多个"Value"字典里面"ResourceRecords",并有可能有几个"Name"出现。

    records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 
    
    name_to_find = "dev1.abc.com." 
    return_values = map(lambda sub_dict: [sub_list["Value"] for sub_list in sub_dict["ResourceRecords"]], 
            filter(lambda sub_dict: sub_dict["Name"] == name_to_find, 
              records["ResourceRecordSets"])) 
    
    print(list(return_dicts)) 
    
  • 如果仅存在一个"Value""ResourceRecords"内部字典和可能存在几个"Name"发生。

    records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 
    
    name_to_find = "dev1.abc.com." 
    return_values = map(lambda sub_dict: sub_dict["ResourceRecords"][0]["Value"], 
            filter(lambda sub_dict: sub_dict["Name"] == name_to_find, 
              records["ResourceRecordSets"])) 
    
    print(list(return_dicts)) 
    
  • 如果只有一个"Name"发生,你最好使用一个for each环路与一休:

    records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 
    
    name_to_find = 'dev1.abc.com.' 
    return_values = [] 
    for sub_dict in records['ResourceRecordSets']: 
        if sub_dict['Name'] == name_to_find: 
         return_values = [record['Value'] for record in sub_dict['ResourceRecords']] 
         break 
    
+1

OP特别要求“价值”,而不是整个子字典。 –

+0

我忽略了它。我现在会更新答案。 – Strinnityk

2

这应该工作,也许你想以不同的值设置格式:

desired_name = 'dev1.abc.com' 
values = [] 
for resource in all_records['ResourceRecordSets']: 
    if resource['Name'] != desired_name: 
     continue 
    values = [record['Value'] for record in resource['ResourceRecords']] 
    break 

print(values) 

同样的逻辑,但@ quamrana的建议:

desired_name = 'dev1.abc.com' 
values = [] 
for resource in all_records['ResourceRecordSets']: 
    if resource['Name'] == desired_name: 
     values = [record['Value'] for record in resource['ResourceRecords']] 
     break 

print(values) 
+1

Paco H,我认为你应该反转'desired_name'的测试来制作更简单的代码。 – quamrana

+0

@quamrana感谢您的评论,我添加了您的建议作为另一种选择。我个人比较喜欢我这样做的方式,但归结为个人品味。 –

+1

Paco H,谢谢你包括我的建议。我个人的口味是代码行数少,在这种情况下,将提取值的操作更接近关于选择哪条记录的决定。 – quamrana

0

我不知道这是否是一个错字,但你确实有在dev1.abc.com.

all_records = {u'ResourceRecordSets': [{u'ResourceRecords': [{u'Value': '10.0.3.214'}], u'Type': 'A', u'Name': 'dev1.abc.com.', u'TTL': 300}, {u'ResourceRecords': [{u'Value': '10.0.3.67'}], u'Type': 'A', u'Name': 'dev2.abc.com', u'TTL': 300}]} 

name = 'dev1.abc.com.' 
for x in all_records['ResourceRecordSets']: 
    if x['Name'] == name: 
     value = x['ResourceRecords'][0]['Value'] 

print(value) 
# 10.0.3.214 
0

这简单得多。不需要中断声明。

for i in range(len(all_records['ResourceRecordSets'])): if(all_records['ResourceRecordSets'][i]['Name']== 'dev1.abc.com.'): print all_records['ResourceRecordSets'][i]['ResourceRecords'][0]['Value']

+1

这仅适用于每个'i'的'all_records ['ResourceRecordSets'] [i] ['ResourceRecords']中只有一条记录。 @ paco-h提供了适用于任何数量记录的解决方案。 –

+0

我同意,但这是这个特定问题所需要的。对于'all_records ['ResourceRecordSets'] [i] ['ResourceRecords']中的n个值,包含另一个循环来说明所有可能的值是微不足道的。 – Pankaj

+0

由于数据显然由DNS记录组成(即“名称”是FQDN,“值”包含IP地址),因此只有样本不包含每个名称的多个值才是偶然事件。 DNS允许许多IP地址用于单个FQDN,所以我会考虑到这一点。 –

0
In [10]: new = list(filter(lambda x: x[u'Name'] == 'dev1.abc.com.', all_records[u'ResourceRecordSets']))[0]['ResourceRecords'] 

In [11]: new 
Out[11]: [{'Value': '10.0.3.214'}]